openssh-7.2p2004075500017500001750000000000001267007037400114045ustar00djmdjmopenssh-7.2p2/.cvsignore010064400017500001750000000004311267006270000134500ustar00djmdjm*.0 *.out Makefile autom4te.cache buildit.sh buildpkg.sh config.cache config.h config.h.in config.log config.status configure openssh.xml opensshd.init scp sftp sftp-server ssh ssh-add ssh-agent ssh-keygen ssh-keyscan ssh-keysign ssh-pkcs11-helper sshd stamp-h.in survey survey.sh openssh-7.2p2/CREDITS010064400017500001750000000126511267006270000124770ustar00djmdjmTatu Ylonen - Creator of SSH Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song - Creators of OpenSSH Ahsan Rashid - UnixWare long passwords Alain St-Denis - Irix fix Alexandre Oliva - AIX fixes Andre Lucas - new login code, many fixes Andreas Steinmetz - Shadow password expiry support Andrew McGill - SCO fixes Andrew Morgan - PAM bugfixes Andrew Stribblehill - Bugfixes Andy Sloane - bugfixes Aran Cox - SCO bugfixes Arkadiusz Miskiewicz - IPv6 compat fixes Ben Lindstrom - NeXT support Ben Taylor - Solaris debugging and fixes Bratislav ILICH - Configure fix Charles Levert - SunOS 4 & bug fixes Chip Salzenberg - Assorted patches Chris Adams - OSF SIA support Chris Saia - SuSE packaging Chris, the Young One - Password auth fixes Christos Zoulas - Autoconf fixes Chun-Chung Chen - RPM fixes Corinna Vinschen - Cygwin support Chad Mynhier - Solaris Process Contract support Dan Brosemer - Autoconf support, build fixes Darren Hall - AIX patches Darren Tucker - AIX BFF package scripts David Agraz - Build fixes David Del Piero - bug fixes David Hesprich - Configure fixes David Rankin - libwrap, AIX, NetBSD fixes Dag-Erling Smørgrav - Challenge-Response PAM code. Dhiraj Gulati - UnixWare long passwords Ed Eden - configure fixes Garrick James - configure fixes Gary E. Miller - SCO support Ged Lodder - HPUX fixes and enhancements Gert Doering - bug and portability fixes HARUYAMA Seigo - Translations & doc fixes Hideaki YOSHIFUJI - IPv6 and bug fixes Hiroshi Takekawa - Configure fixes Holger Trapp - KRB4/AFS config patch IWAMURO Motonori - bugfixes Jani Hakala - Patches Jarno Huuskonen - Bugfixes Jim Knoble - Many patches Jonchen (email unknown) - the original author of PAM support of SSH Juergen Keil - scp bugfixing KAMAHARA Junzo - Configure fixes Kees Cook - scp fixes Kenji Miyake - Configure fixes Kevin Cawlfield - AIX fixes. Kevin O'Connor - RSAless operation Kevin Steves - HP support, bugfixes, improvements Kiyokazu SUTO - Bugfixes Larry Jones - Bugfixes Lutz Jaenicke - Bugfixes Marc G. Fournier - Solaris patches Mark D. Baushke - bug fixes Martin Johansson - Linux fixes Mark D. Roth - Features, bug fixes Mark Miller - Bugfixes Matt Richards - AIX patches Michael Steffens - HP-UX fixes Michael Stone - Irix enhancements Nakaji Hiroyuki - Sony News-OS patch Nalin Dahyabhai - PAM environment patch Nate Itkin - SunOS 4.1.x fixes Niels Kristian Bech Jensen - Assorted patches Pavel Kankovsky - Security fixes Pavel Troller - Bugfixes Pekka Savola - Bugfixes Peter Kocks - Makefile fixes Peter Stuge - mdoc2man.awk script Phil Hands - Debian scripts, assorted patches Phil Karn - Autoconf fixes Philippe WILLEM - Bugfixes Phill Camp - login code fix Rip Loomis - Solaris package support, fixes Robert Dahlem - Reliant Unix fixes Roumen Petrov - Compile & configure fixes SAKAI Kiyotaka - Multiple bugfixes Simon Wilkinson - PAM fixes, Compat with MIT KrbV Solar Designer - many patches and technical assistance Svante Signell - Bugfixes Thomas Neumann - Shadow passwords Tim Rice - Portability & SCO fixes Tobias Oetiker - Bugfixes Tom Bertelson's - AIX auth fixes Tor-Ake Fransson - AIX support Tudor Bosman - MD5 password support Udo Schweigert - ReliantUNIX support Wendy Palm - Cray support. Zack Weinberg - GNOME askpass enhancement Apologies to anyone I have missed. Damien Miller $Id: CREDITS,v 1.81 2006/08/30 17:24:41 djm Exp $ openssh-7.2p2/INSTALL010064400017500001750000000215651267006270000125140ustar00djmdjm1. Prerequisites ---------------- You will need working installations of Zlib and libcrypto (LibreSSL / OpenSSL) Zlib 1.1.4 or 1.2.1.2 or greater (ealier 1.2.x versions have problems): http://www.gzip.org/zlib/ libcrypto (LibreSSL or OpenSSL >= 0.9.8f) LibreSSL http://www.libressl.org/ ; or OpenSSL http://www.openssl.org/ LibreSSL/OpenSSL should be compiled as a position-independent library (i.e. with -fPIC) otherwise OpenSSH will not be able to link with it. If you must use a non-position-independent libcrypto, then you may need to configure OpenSSH --without-pie. The remaining items are optional. NB. If you operating system supports /dev/random, you should configure libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's direct support of /dev/random, or failing that, either prngd or egd PRNGD: If your system lacks kernel-based random collection, the use of Lutz Jaenicke's PRNGd is recommended. http://prngd.sourceforge.net/ EGD: If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is supported only if libcrypto supports it. http://egd.sourceforge.net/ PAM: OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system supports it. PAM is standard most Linux distributions, Solaris, HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD. Information about the various PAM implementations are available: Solaris PAM: http://www.sun.com/software/solaris/pam/ Linux PAM: http://www.kernel.org/pub/linux/libs/pam/ OpenPAM: http://www.openpam.org/ If you wish to build the GNOME passphrase requester, you will need the GNOME libraries and headers. GNOME: http://www.gnome.org/ Alternatively, Jim Knoble has written an excellent X11 passphrase requester. This is maintained separately at: http://www.jmknoble.net/software/x11-ssh-askpass/ 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/ LDNS: LDNS is a DNS BSD-licensed resolver library which supports DNSSEC. http://nlnetlabs.nl/projects/ldns/ 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.68 to rebuild the automatically generated files by running "autoreconf". Earlier versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ 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-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 sshd.pid file is created. --with-xauth=PATH specifies the location of the xauth binary --with-ssl-dir=DIR allows you to specify where your Libre/OpenSSL libraries are installed. --with-ssl-engine enables Libre/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. 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.91 2014/09/09 02:23:11 dtucker Exp $ openssh-7.2p2/LICENCE010064400017500001750000000372501267006270000124460ustar00djmdjmThis 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 , 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 * 3) ssh-keyscan was contributed by David Mazieres under a BSD-style license. * Copyright 1995, 1996 by David Mazieres . * * 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 * @author Antoon Bosselaers * @author Paulo Barreto * * 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 Daniel Walsh Red Hat, Inc Simon Vallet / Genoscope * 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): * 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 $ openssh-7.2p2/Makefile.in010064400017500001750000000546531267006270000135340ustar00djmdjm# $Id: Makefile.in,v 1.365 2014/08/30 06:23:07 djm 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 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ STRIP_OPT=@STRIP_OPT@ TEST_SHELL=@TEST_SHELL@ 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_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ LIBS=@LIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHLIBS=@SSHLIBS@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ 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@ MANFMT=@MANFMT@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) LIBOPENSSH_OBJS=\ ssh_api.o \ ssherr.o \ sshbuf.o \ sshkey.o \ sshbuf-getput-basic.o \ sshbuf-misc.o \ sshbuf-getput-crypto.o \ krl.o \ bitmap.o LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ compat.o crc32.o deattack.o fatal.o hostfile.o \ log.o match.o md-sha256.o moduli.o nchan.o packet.o opacket.o \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o \ ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ platform-pledge.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ audit.o audit-bsm.o audit-linux.o platform.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 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 \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ sandbox-solaris.o MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.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_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_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_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|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \ -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ -e 's|/etc/moduli|$(sysconfdir)/moduli|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) FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \ @UNSUPPORTED_ALGORITHMS@ all: $(CONFIGFILES) $(MANPAGES) $(TARGETS) $(LIBSSH_OBJS): Makefile.in config.h $(SSHOBJS): Makefile.in config.h $(SSHDOBJS): Makefile.in config.h .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ 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 $(SSHLIBS) $(LIBS) $(GSSLIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) 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 ssh-pkcs11-client.o $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.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 readconf.o $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -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 sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.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) # 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} | $(FIXALGORITHMSCMD) | \ $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \ else \ $(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \ fi $(CONFIGFILES): $(CONFIGFILES_IN) conffile=`echo $@ | sed 's/.out$$//'`; \ $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ # fake rule to stop make trying to compile moduli.o into a binary "moduli.o" moduli: echo # special case target for umac128 umac128.o: umac.c $(CC) $(CFLAGS) $(CPPFLAGS) -o umac128.o -c $(srcdir)/umac.c \ -DUMAC_OUTPUT_LEN=16 -Dumac_new=umac128_new \ -Dumac_update=umac128_update -Dumac_final=umac128_final \ -Dumac_delete=umac128_delete clean: regressclean rm -f *.o *.a $(TARGETS) logintest config.cache config.log rm -f *.out core survey rm -f regress/unittests/test_helper/*.a rm -f regress/unittests/test_helper/*.o rm -f regress/unittests/sshbuf/*.o rm -f regress/unittests/sshbuf/test_sshbuf rm -f regress/unittests/sshkey/*.o rm -f regress/unittests/sshkey/test_sshkey rm -f regress/unittests/bitmap/*.o rm -f regress/unittests/bitmap/test_bitmap rm -f regress/unittests/hostkeys/*.o rm -f regress/unittests/hostkeys/test_hostkeys rm -f regress/unittests/kex/*.o rm -f regress/unittests/kex/test_kex (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 rm -f survey.sh openbsd-compat/regress/Makefile *~ rm -rf autom4te.cache rm -f regress/unittests/test_helper/*.a rm -f regress/unittests/test_helper/*.o rm -f regress/unittests/sshbuf/*.o rm -f regress/unittests/sshbuf/test_sshbuf rm -f regress/unittests/sshkey/*.o rm -f regress/unittests/sshkey/test_sshkey rm -f regress/unittests/bitmap/*.o rm -f regress/unittests/bitmap/test_bitmap rm -f regress/unittests/hostkeys/*.o rm -f regress/unittests/hostkeys/test_hostkeys rm -f regress/unittests/kex/*.o rm -f regress/unittests/kex/test_kex (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ fi veryclean: distclean rm -f configure config.h.in *.0 cleandir: veryclean mrproper: veryclean realclean: veryclean catman-do: @for f in $(MANPAGES_IN) ; do \ base=`echo $$f | sed 's/\..*$$//'` ; \ echo "$$f -> $$base.0" ; \ $(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \ >$$base.0 ; \ done distprep: catman-do $(AUTORECONF) -rm -rf autom4te.cache install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf install-nosysconf: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files check-config: -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config install-files: $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir) $(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$(EXEEXT) $(DESTDIR)$(bindir)/ssh$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) scp$(EXEEXT) $(DESTDIR)$(bindir)/scp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-add$(EXEEXT) $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent$(EXEEXT) $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) $(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 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5 $(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 $(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 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 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 $(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 \ ./ssh-keygen -A; \ fi host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT) if ./ssh -Q protocol-version | grep '^1$$' >/dev/null; then \ ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""; \ fi ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N "" if ./ssh -Q key | grep ecdsa >/dev/null ; then \ ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""; \ fi uninstallall: uninstall -rm -f $(DESTDIR)$(sysconfdir)/ssh_config -rm -f $(DESTDIR)$(sysconfdir)/sshd_config -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)/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)$(SSH_PKCS11_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/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 regress-prep: [ -d `pwd`/regress ] || mkdir -p `pwd`/regress [ -d `pwd`/regress/unittests ] || mkdir -p `pwd`/regress/unittests [ -d `pwd`/regress/unittests/test_helper ] || \ mkdir -p `pwd`/regress/unittests/test_helper [ -d `pwd`/regress/unittests/sshbuf ] || \ mkdir -p `pwd`/regress/unittests/sshbuf [ -d `pwd`/regress/unittests/sshkey ] || \ mkdir -p `pwd`/regress/unittests/sshkey [ -d `pwd`/regress/unittests/bitmap ] || \ mkdir -p `pwd`/regress/unittests/bitmap [ -d `pwd`/regress/unittests/hostkeys ] || \ mkdir -p `pwd`/regress/unittests/hostkeys [ -d `pwd`/regress/unittests/kex ] || \ mkdir -p `pwd`/regress/unittests/kex [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_HELPER_OBJS=\ regress/unittests/test_helper/test_helper.o \ regress/unittests/test_helper/fuzz.o regress/unittests/test_helper/libtest_helper.a: ${UNITTESTS_TEST_HELPER_OBJS} $(AR) rv $@ $(UNITTESTS_TEST_HELPER_OBJS) $(RANLIB) $@ UNITTESTS_TEST_SSHBUF_OBJS=\ regress/unittests/sshbuf/tests.o \ regress/unittests/sshbuf/test_sshbuf.o \ regress/unittests/sshbuf/test_sshbuf_getput_basic.o \ regress/unittests/sshbuf/test_sshbuf_getput_crypto.o \ regress/unittests/sshbuf/test_sshbuf_misc.o \ regress/unittests/sshbuf/test_sshbuf_fuzz.o \ regress/unittests/sshbuf/test_sshbuf_getput_fuzz.o \ regress/unittests/sshbuf/test_sshbuf_fixed.o regress/unittests/sshbuf/test_sshbuf$(EXEEXT): ${UNITTESTS_TEST_SSHBUF_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHBUF_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_SSHKEY_OBJS=\ regress/unittests/sshkey/test_fuzz.o \ regress/unittests/sshkey/tests.o \ regress/unittests/sshkey/common.o \ regress/unittests/sshkey/test_file.o \ regress/unittests/sshkey/test_sshkey.o regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHKEY_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_BITMAP_OBJS=\ regress/unittests/bitmap/tests.o regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_BITMAP_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_KEX_OBJS=\ regress/unittests/kex/tests.o \ regress/unittests/kex/test_kex.o regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_KEX_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_HOSTKEYS_OBJS=\ regress/unittests/hostkeys/tests.o \ regress/unittests/hostkeys/test_iterate.o regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \ ${UNITTESTS_TEST_HOSTKEYS_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_HOSTKEYS_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) REGRESS_BINARIES=\ regress/modpipe$(EXEEXT) \ regress/setuid-allowed$(EXEEXT) \ regress/netcat$(EXEEXT) \ regress/check-perm$(EXEEXT) \ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/bitmap/test_bitmap$(EXEEXT) \ regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \ regress/unittests/kex/test_kex$(EXEEXT) tests interop-tests t-exec: regress-prep $(TARGETS) $(REGRESS_BINARIES) BUILDDIR=`pwd`; \ TEST_SSH_SCP="$${BUILDDIR}/scp"; \ 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_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper"; \ TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ TEST_SSH_PLINK="plink"; \ TEST_SSH_PUTTYGEN="puttygen"; \ TEST_SSH_CONCH="conch"; \ TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \ TEST_SSH_ECC="@TEST_SSH_ECC@" ; \ cd $(srcdir)/regress || exit $$?; \ $(MAKE) \ .OBJDIR="$${BUILDDIR}/regress" \ .CURDIR="`pwd`" \ BUILDDIR="$${BUILDDIR}" \ OBJ="$${BUILDDIR}/regress/" \ PATH="$${BUILDDIR}:$${PATH}" \ TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ TEST_SSH_SCP="$${TEST_SSH_SCP}" \ 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_SSHPKCS11HELPER="$${TEST_SSH_SSHPKCS11HELPER}" \ TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \ TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \ TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \ TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \ TEST_SSH_ECC="$${TEST_SSH_ECC}" \ TEST_SHELL="${TEST_SHELL}" \ EXEEXT="$(EXEEXT)" \ $@ && echo all tests passed 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 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 (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.12 2015/07/08 19:01:15 markus Exp $ openssh-7.2p2/PROTOCOL010064400017500001750000000405551267006270000126470ustar00djmdjmThis documents OpenSSH's deviations and extensions to the published SSH protocol. Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH filexfer protocol described in: http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt Newer versions of the draft will not be supported, though some features are individually implemented as extensions described below. The protocol used by OpenSSH's ssh-agent is described in the file PROTOCOL.agent 1. Transport protocol changes 1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" This is a new transport-layer MAC method using the UMAC algorithm (rfc4418). This method is identical to the "umac-64" method documented in: http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt 1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com" This transport-layer compression method uses the zlib compression algorithm (identical to the "zlib" method in rfc4253), but delays the start of compression until after authentication has completed. This avoids exposing compression code to attacks from unauthenticated users. The method is documented in: http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt 1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com", "ssh-dsa-cert-v00@openssh.com", "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ecdsa-sha2-nistp384-cert-v01@openssh.com" and "ecdsa-sha2-nistp521-cert-v01@openssh.com" OpenSSH introduces new public key algorithms to support certificate authentication for users and host keys. These methods are documented in the file PROTOCOL.certkeys 1.4. transport: Elliptic Curve cryptography OpenSSH supports ECC key exchange and public key authentication as specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic curve points encoded using point compression are NOT accepted or generated. 1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms OpenSSH supports MAC algorithms, whose names contain "-etm", that perform the calculations in a different order to that defined in RFC 4253. These variants use the so-called "encrypt then MAC" ordering, calculating the MAC over the packet ciphertext rather than the plaintext. This ordering closes a security flaw in the SSH transport protocol, where decryption of unauthenticated ciphertext provided a "decryption oracle" that could, in conjunction with cipher flaws, reveal session plaintext. Specifically, the "-etm" MAC algorithms modify the transport protocol to calculate the MAC over the packet ciphertext and to send the packet length unencrypted. This is necessary for the transport to obtain the length of the packet and location of the MAC tag so that it may be verified without decrypting unauthenticated data. As such, the MAC covers: mac = MAC(key, sequence_number || packet_length || encrypted_packet) where "packet_length" is encoded as a uint32 and "encrypted_packet" contains: byte padding_length byte[n1] payload; n1 = packet_length - padding_length - 1 byte[n2] random padding; n2 = padding_length 1.6 transport: AES-GCM OpenSSH supports the AES-GCM algorithm as specified in RFC 5647. Because of problems with the specification of the key exchange the behaviour of OpenSSH differs from the RFC as follows: AES-GCM is only negotiated as the cipher algorithms "aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as an MAC algorithm. Additionally, if AES-GCM is selected as the cipher the exchanged MAC algorithms are ignored and there doesn't have to be a matching MAC. 1.7 transport: chacha20-poly1305@openssh.com authenticated encryption OpenSSH supports authenticated encryption using ChaCha20 and Poly1305 as described in PROTOCOL.chacha20poly1305. 1.8 transport: curve25519-sha256@libssh.org key exchange algorithm OpenSSH supports the use of ECDH in Curve25519 for key exchange as described at: http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519 2. Connection protocol changes 2.1. connection: Channel write close extension "eow@openssh.com" The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF message to allow an endpoint to signal its peer that it will send no more data over a channel. Unfortunately, there is no symmetric way for an endpoint to request that its peer should cease sending data to it while still keeping the channel open for the endpoint to send data to the peer. This is desirable, since it saves the transmission of data that would otherwise need to be discarded and it allows an endpoint to signal local processes of the condition, e.g. by closing the corresponding file descriptor. OpenSSH implements a channel extension message to perform this signalling: "eow@openssh.com" (End Of Write). This message is sent by an endpoint when the local output of a session channel is closed or experiences a write error. The message is formatted as follows: byte SSH_MSG_CHANNEL_REQUEST uint32 recipient channel string "eow@openssh.com" boolean FALSE On receiving this message, the peer SHOULD cease sending data of the channel and MAY signal the process from which the channel data originates (e.g. by closing its read file descriptor). As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does remain open after a "eow@openssh.com" has been sent and more data may still be sent in the other direction. This message does not consume window space and may be sent even if no window space is available. NB. due to certain broken SSH implementations aborting upon receipt of this message (in contravention of RFC4254 section 5.4), this message is only sent to OpenSSH peers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. 2.2. connection: disallow additional sessions extension "no-more-sessions@openssh.com" Most SSH connections will only ever request a single session, but a attacker may abuse a running ssh client to surreptitiously open additional sessions under their control. OpenSSH provides a global request "no-more-sessions@openssh.com" to mitigate this attack. When an OpenSSH client expects that it will never open another session (i.e. it has been started with connection multiplexing disabled), it will send the following global request: byte SSH_MSG_GLOBAL_REQUEST string "no-more-sessions@openssh.com" char want-reply On receipt of such a message, an OpenSSH server will refuse to open future channels of type "session" and instead immediately abort the connection. Note that this is not a general defence against compromised clients (that is impossible), but it thwarts a simple attack. NB. due to certain broken SSH implementations aborting upon receipt of this message, the no-more-sessions request is only sent to OpenSSH servers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. 2.3. connection: Tunnel forward extension "tun@openssh.com" OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" channel type. This channel type supports forwarding of network packets with datagram boundaries intact between endpoints equipped with interfaces like the BSD tun(4) device. Tunnel forwarding channels are requested by the client with the following packet: byte SSH_MSG_CHANNEL_OPEN string "tun@openssh.com" uint32 sender channel uint32 initial window size uint32 maximum packet size uint32 tunnel mode uint32 remote unit number The "tunnel mode" parameter specifies whether the tunnel should forward layer 2 frames or layer 3 packets. It may take one of the following values: SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */ SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */ The "tunnel unit number" specifies the remote interface number, or may be 0x7fffffff to allow the server to automatically chose an interface. A server that is not willing to open a client-specified unit should refuse the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS. Once established the client and server may exchange packet or frames over the tunnel channel by encapsulating them in SSH protocol strings and sending them as channel data. This ensures that packet boundaries are kept intact. Specifically, packets are transmitted using normal SSH_MSG_CHANNEL_DATA packets: byte SSH_MSG_CHANNEL_DATA uint32 recipient channel string data The contents of the "data" field for layer 3 packets is: uint32 packet length uint32 address family byte[packet length - 4] packet data The "address family" field identifies the type of packet in the message. It may be one of: SSH_TUN_AF_INET 2 /* IPv4 */ SSH_TUN_AF_INET6 24 /* IPv6 */ The "packet data" field consists of the IPv4/IPv6 datagram itself without any link layer header. The contents of the "data" field for layer 2 packets is: uint32 packet length byte[packet length] frame The "frame" field contains an IEEE 802.3 Ethernet frame, including header. 2.4. connection: Unix domain socket forwarding OpenSSH supports local and remote Unix domain socket forwarding using the "streamlocal" extension. Forwarding is initiated as per TCP sockets but with a single path instead of a host and port. Similar to direct-tcpip, direct-streamlocal is sent by the client to request that the server make a connection to a Unix domain socket. byte SSH_MSG_CHANNEL_OPEN string "direct-streamlocal@openssh.com" uint32 sender channel uint32 initial window size uint32 maximum packet size string socket path Similar to forwarded-tcpip, forwarded-streamlocal is sent by the server when the client has previously send the server a streamlocal-forward GLOBAL_REQUEST. byte SSH_MSG_CHANNEL_OPEN string "forwarded-streamlocal@openssh.com" uint32 sender channel uint32 initial window size uint32 maximum packet size string socket path string reserved for future use The reserved field is not currently defined and is ignored on the remote end. It is intended to be used in the future to pass information about the socket file, such as ownership and mode. The client currently sends the empty string for this field. Similar to tcpip-forward, streamlocal-forward is sent by the client to request remote forwarding of a Unix domain socket. byte SSH2_MSG_GLOBAL_REQUEST string "streamlocal-forward@openssh.com" boolean TRUE string socket path Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent by the client cancel the forwarding of a Unix domain socket. byte SSH2_MSG_GLOBAL_REQUEST string "cancel-streamlocal-forward@openssh.com" boolean FALSE string socket path 2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com" and "hostkeys-prove-00@openssh.com" OpenSSH supports a protocol extension allowing a server to inform a client of all its protocol v.2 host keys after user-authentication has completed. byte SSH_MSG_GLOBAL_REQUEST string "hostkeys-00@openssh.com" string[] hostkeys Upon receiving this message, a client should check which of the supplied host keys are present in known_hosts. For keys that are not present, it should send a "hostkeys-prove@openssh.com" message to request the server prove ownership of the private half of the key. byte SSH_MSG_GLOBAL_REQUEST string "hostkeys-prove-00@openssh.com" char 1 /* want-reply */ string[] hostkeys When a server receives this message, it should generate a signature using each requested key over the following: string "hostkeys-prove-00@openssh.com" string session identifier string hostkey These signatures should be included in the reply, in the order matching the hostkeys in the request: byte SSH_MSG_REQUEST_SUCCESS string[] signatures When the client receives this reply (and not a failure), it should validate the signatures and may update its known_hosts file, adding keys that it has not seen before and deleting keys for the server host that are no longer offered. These extensions let a client learn key types that it had not previously encountered, thereby allowing it to potentially upgrade from weaker key algorithms to better ones. It also supports graceful key rotation: a server may offer multiple keys of the same type for a period (to give clients an opportunity to learn them using this extension) before removing the deprecated key from those offered. 3. SFTP protocol changes 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK When OpenSSH's sftp-server was implemented, the order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, the reversal was not noticed until the server was widely deployed. Since fixing this to follow the specification would cause incompatibility, the current order was retained. For correct operation, clients should send SSH_FXP_SYMLINK as follows: uint32 id string targetpath string linkpath 3.2. sftp: Server extension announcement in SSH_FXP_VERSION OpenSSH's sftp-server lists the extensions it supports using the standard extension announcement mechanism in the SSH_FXP_VERSION server hello packet: uint32 3 /* protocol version */ string ext1-name string ext1-version string ext2-name string ext2-version ... string extN-name string extN-version Each extension reports its integer version number as an ASCII encoded string, e.g. "1". The version will be incremented if the extension is ever changed in an incompatible way. The server MAY advertise the same extension with multiple versions (though this is unlikely). Clients MUST check the version number before attempting to use the extension. 3.3. sftp: Extension request "posix-rename@openssh.com" This operation provides a rename operation with POSIX semantics, which are different to those provided by the standard SSH_FXP_RENAME in draft-ietf-secsh-filexfer-02.txt. This request is implemented as a SSH_FXP_EXTENDED request with the following format: uint32 id string "posix-rename@openssh.com" string oldpath string newpath On receiving this request the server will perform the POSIX operation rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". 3.4. sftp: Extension requests "statvfs@openssh.com" and "fstatvfs@openssh.com" These requests correspond to the statvfs and fstatvfs POSIX system interfaces. The "statvfs@openssh.com" request operates on an explicit pathname, and is formatted as follows: uint32 id string "statvfs@openssh.com" string path The "fstatvfs@openssh.com" operates on an open file handle: uint32 id string "fstatvfs@openssh.com" string handle These requests return a SSH_FXP_STATUS reply on failure. On success they return the following SSH_FXP_EXTENDED_REPLY reply: uint32 id uint64 f_bsize /* file system block size */ uint64 f_frsize /* fundamental fs block size */ uint64 f_blocks /* number of blocks (unit f_frsize) */ uint64 f_bfree /* free blocks in file system */ uint64 f_bavail /* free blocks for non-root */ uint64 f_files /* total file inodes */ uint64 f_ffree /* free file inodes */ uint64 f_favail /* free file inodes for to non-root */ uint64 f_fsid /* file system id */ uint64 f_flag /* bit mask of f_flag values */ uint64 f_namemax /* maximum filename length */ The values of the f_flag bitmask are as follows: #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */ #define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */ Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". 10. sftp: Extension request "hardlink@openssh.com" This request is for creating a hard link to a regular file. This request is implemented as a SSH_FXP_EXTENDED request with the following format: uint32 id string "hardlink@openssh.com" string oldpath string newpath On receiving this request the server will perform the operation link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". 10. sftp: Extension request "fsync@openssh.com" This request asks the server to call fsync(2) on an open file handle. uint32 id string "fsync@openssh.com" string handle One receiving this request, a server will call fsync(handle_fd) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". $OpenBSD: PROTOCOL,v 1.29 2015/07/17 03:09:19 djm Exp $ openssh-7.2p2/PROTOCOL.agent010064400017500001750000000430721267006270000137410ustar00djmdjmThis describes the protocol used by OpenSSH's ssh-agent. OpenSSH's agent supports managing keys for the standard SSH protocol 2 as well as the legacy SSH protocol 1. Support for these key types is almost completely disjoint - in all but a few cases, operations on protocol 2 keys cannot see or affect protocol 1 keys and vice-versa. Protocol 1 and protocol 2 keys are separated because of the differing cryptographic usage: protocol 1 private RSA keys are used to decrypt challenges that were encrypted with the corresponding public key, whereas protocol 2 RSA private keys are used to sign challenges with a private key for verification with the corresponding public key. It is considered unsound practice to use the same key for signing and encryption. With a couple of exceptions, the protocol message names used in this document indicate which type of key the message relates to. SSH_* messages refer to protocol 1 keys only. SSH2_* messages refer to protocol 2 keys. Furthermore, the names also indicate whether the message is a request to the agent (*_AGENTC_*) or a reply from the agent (*_AGENT_*). Section 3 below contains the mapping of the protocol message names to their integer values. 1. Data types Because of support for legacy SSH protocol 1 keys, OpenSSH's agent protocol makes use of some data types not defined in RFC 4251. 1.1 uint16 The "uint16" data type is a simple MSB-first 16 bit unsigned integer encoded in two bytes. 1.2 mpint1 The "mpint1" type represents an arbitrary precision integer (bignum). Its format is as follows: uint16 bits byte[(bits + 7) / 8] bignum "bignum" contains an unsigned arbitrary precision integer encoded as eight bits per byte in big-endian (MSB first) format. Note the difference between the "mpint1" encoding and the "mpint" encoding defined in RFC 4251. Also note that the length of the encoded integer is specified in bits, not bytes and that the byte length of the integer must be calculated by rounding up the number of bits to the nearest eight. 2. Protocol Messages All protocol messages are prefixed with their length in bytes, encoded as a 32 bit unsigned integer. Specifically: uint32 message_length byte[message_length] message The following message descriptions refer only to the content the "message" field. 2.1 Generic server responses The following generic messages may be sent by the server in response to requests from the client. On success the agent may reply either with: byte SSH_AGENT_SUCCESS or a request-specific success message. On failure, the agent may reply with: byte SSH_AGENT_FAILURE SSH_AGENT_FAILURE messages are also sent in reply to unknown request types. 2.2 Adding keys to the agent Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys respectively. Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional "constraints" on their usage. OpenSSH may be built with support for keys hosted on a smartcard or other hardware security module. These keys may be added to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests. 2.2.1 Key constraints The OpenSSH agent supports some basic optional constraints on key usage. At present there are two constraints defined. The first constraint limits the validity duration of a key. It is encoded as: byte SSH_AGENT_CONSTRAIN_LIFETIME uint32 seconds Where "seconds" contains the number of seconds that the key shall remain valid measured from the moment that the agent receives it. After the validity period has expired, OpenSSH's agent will erase these keys from memory. The second constraint requires the agent to seek explicit user confirmation before performing private key operations with the loaded key. This constraint is encoded as: byte SSH_AGENT_CONSTRAIN_CONFIRM Zero or more constraints may be specified when adding a key with one of the *_CONSTRAINED requests. Multiple constraints are appended consecutively to the end of the request: byte constraint1_type .... constraint1_data byte constraint2_type .... constraint2_data .... byte constraintN_type .... constraintN_data Such a sequence of zero or more constraints will be referred to below as "constraint[]". Agents may determine whether there are constraints by checking whether additional data exists in the "add key" request after the key data itself. OpenSSH will refuse to add a key if it contains unknown constraints. 2.2.2 Add protocol 1 key A client may add a protocol 1 key to an agent with the following request: byte SSH_AGENTC_ADD_RSA_IDENTITY or SSH_AGENTC_ADD_RSA_ID_CONSTRAINED uint32 ignored mpint1 rsa_n mpint1 rsa_e mpint1 rsa_d mpint1 rsa_iqmp mpint1 rsa_q mpint1 rsa_p string key_comment constraint[] key_constraints Note that there is some redundancy in the key parameters; a key could be fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra computation. "key_constraints" may only be present if the request type is SSH_AGENTC_ADD_RSA_ID_CONSTRAINED. The agent will reply with a SSH_AGENT_SUCCESS if the key has been successfully added or a SSH_AGENT_FAILURE if an error occurred. 2.2.3 Add protocol 2 key The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA keys may be added using the following request byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-dss" mpint dsa_p mpint dsa_q mpint dsa_g mpint dsa_public_key mpint dsa_private_key string key_comment constraint[] key_constraints DSA certificates may be added with: byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-dss-cert-v00@openssh.com" string certificate mpint dsa_private_key string key_comment constraint[] key_constraints ECDSA keys may be added using the following request byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ecdsa-sha2-nistp256" | "ecdsa-sha2-nistp384" | "ecdsa-sha2-nistp521" string ecdsa_curve_name string ecdsa_public_key mpint ecdsa_private string key_comment constraint[] key_constraints ECDSA certificates may be added with: byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | "ecdsa-sha2-nistp384-cert-v01@openssh.com" | "ecdsa-sha2-nistp521-cert-v01@openssh.com" string certificate mpint ecdsa_private_key string key_comment constraint[] key_constraints RSA keys may be added with this request: byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-rsa" mpint rsa_n mpint rsa_e mpint rsa_d mpint rsa_iqmp mpint rsa_p mpint rsa_q string key_comment constraint[] key_constraints RSA certificates may be added with this request: byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-rsa-cert-v00@openssh.com" string certificate mpint rsa_d mpint rsa_iqmp mpint rsa_p mpint rsa_q string key_comment constraint[] key_constraints Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse order to the protocol 1 add keys message. As with the corresponding protocol 1 "add key" request, the private key is overspecified to avoid redundant processing. For DSA, ECDSA and RSA key add requests, "key_constraints" may only be present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. The agent will reply with a SSH_AGENT_SUCCESS if the key has been successfully added or a SSH_AGENT_FAILURE if an error occurred. 2.2.4 Loading keys from a smartcard The OpenSSH agent may have optional smartcard support built in to it. If so, it supports an operation to load keys from a smartcard. Technically, only the public components of the keys are loaded into the agent so this operation really arranges for future private key operations to be delegated to the smartcard. byte SSH_AGENTC_ADD_SMARTCARD_KEY or SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED string reader_id string pin constraint[] key_constraints "reader_id" is an identifier to a smartcard reader and "pin" is a PIN or passphrase used to unlock the private key(s) on the device. "key_constraints" may only be present if the request type is SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED. This operation may load all SSH keys that are unlocked using the "pin" on the specified reader. The type of key loaded (protocol 1 or protocol 2) will be specified by the smartcard itself, it is not client-specified. The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have been successfully loaded or a SSH_AGENT_FAILURE if an error occurred. The agent will also return SSH_AGENT_FAILURE if it does not support smartcards. 2.3 Removing multiple keys A client may request that an agent delete all protocol 1 keys using the following request: byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES This message requests the deletion of all protocol 2 keys: byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES On success, the agent will delete all keys of the requested type and reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent will reply with SSH_AGENT_FAILURE. Note that, to delete all keys (both protocol 1 and 2), a client must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a SSH2_AGENTC_REMOVE_ALL_IDENTITIES request. 2.4 Removing specific keys 2.4.1 Removing a protocol 1 key Removal of a protocol 1 key may be requested with the following message: byte SSH_AGENTC_REMOVE_RSA_IDENTITY uint32 key_bits mpint1 rsa_e mpint1 rsa_n Note that key_bits is strictly redundant, as it may be inferred by the length of rsa_n. The agent will delete any private key matching the specified public key and return SSH_AGENT_SUCCESS. If no such key was found, the agent will return SSH_AGENT_FAILURE. 2.4.2 Removing a protocol 2 key Protocol 2 keys may be removed with the following request: byte SSH2_AGENTC_REMOVE_IDENTITY string key_blob Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key Algorithms" for any of the supported protocol 2 key types. The agent will delete any private key matching the specified public key and return SSH_AGENT_SUCCESS. If no such key was found, the agent will return SSH_AGENT_FAILURE. 2.4.3 Removing keys loaded from a smartcard A client may request that a server remove one or more smartcard-hosted keys using this message: byte SSH_AGENTC_REMOVE_SMARTCARD_KEY string reader_id string pin "reader_id" the an identifier to a smartcard reader and "pin" is a PIN or passphrase used to unlock the private key(s) on the device. When this message is received, and if the agent supports smartcard-hosted keys, it will delete all keys that are hosted on the specified smartcard that may be accessed with the given "pin". The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have been successfully removed or a SSH_AGENT_FAILURE if an error occurred. The agent will also return SSH_AGENT_FAILURE if it does not support smartcards. 2.5 Requesting a list of known keys An agent may be requested to list which keys it holds. Different requests exist for protocol 1 and protocol 2 keys. 2.5.1 Requesting a list of protocol 1 keys To request a list of protocol 1 keys that are held in the agent, a client may send the following message: byte SSH_AGENTC_REQUEST_RSA_IDENTITIES The agent will reply with the following message: byte SSH_AGENT_RSA_IDENTITIES_ANSWER uint32 num_keys Followed by zero or more consecutive keys, encoded as: uint32 bits mpint1 rsa_e mpint1 rsa_n string key_comment 2.5.2 Requesting a list of protocol 2 keys A client may send the following message to request a list of protocol 2 keys that are stored in the agent: byte SSH2_AGENTC_REQUEST_IDENTITIES The agent will reply with the following message header: byte SSH2_AGENT_IDENTITIES_ANSWER uint32 num_keys Followed by zero or more consecutive keys, encoded as: string key_blob string key_comment Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key Algorithms" for any of the supported protocol 2 key types. 2.6 Private key operations The purpose of the agent is to perform private key operations, such as signing and encryption without requiring a passphrase to unlock the key and without allowing the private key itself to be exposed. There are separate requests for the protocol 1 and protocol 2 private key operations. 2.6.1 Protocol 1 private key challenge The private key operation used in version 1 of the SSH protocol is decrypting a challenge that has been encrypted with a public key. It may be requested using this message: byte SSH_AGENTC_RSA_CHALLENGE uint32 ignored mpint1 rsa_e mpint1 rsa_n mpint1 encrypted_challenge byte[16] session_id uint32 response_type /* must be 1 */ "rsa_e" and "rsa_n" are used to identify which private key to use. "encrypted_challenge" is a challenge blob that has (presumably) been encrypted with the public key and must be in the range 1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 session ID (computed from the server host key, the server semi-ephemeral key and the session cookie). "ignored" and "response_type" exist for compatibility with legacy implementations. "response_type" must be equal to 1; other response types are not supported. On receiving this request, the server decrypts the "encrypted_challenge" using the private key matching the supplied (rsa_e, rsa_n) values. For the response derivation, the decrypted challenge is represented as an unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values smaller than 2^248 will have leading 0 bytes). The response value is then calculated as: response = MD5(decrypted_challenge || session_id) and returned in the following message byte SSH_AGENT_RSA_RESPONSE byte[16] response If the agent cannot find the key specified by the supplied (rsa_e, rsa_n) then it will return SSH_AGENT_FAILURE. 2.6.2 Protocol 2 private key signature request A client may use the following message to request signing of data using a protocol 2 key: byte SSH2_AGENTC_SIGN_REQUEST string key_blob string data uint32 flags Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key Algorithms" for any of the supported protocol 2 key types. "flags" is a bit-mask, but at present only one possible value is defined (see below for its meaning): SSH_AGENT_OLD_SIGNATURE 1 Upon receiving this request, the agent will look up the private key that corresponds to the public key contained in key_blob. It will use this private key to sign the "data" and produce a signature blob using the key type-specific method described in RFC 4253 section 6.6 "Public Key Algorithms". An exception to this is for "ssh-dss" keys where the "flags" word contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy signature encoding is used in lieu of the standard one. In this case, the DSA signature blob is encoded as: byte[40] signature The signature will be returned in the response message: byte SSH2_AGENT_SIGN_RESPONSE string signature_blob If the agent cannot find the key specified by the supplied key_blob then it will return SSH_AGENT_FAILURE. 2.7 Locking or unlocking an agent The agent supports temporary locking with a passphrase to suspend processing of sensitive operations until it has been unlocked with the same passphrase. To lock an agent, a client send the following request: byte SSH_AGENTC_LOCK string passphrase Upon receipt of this message and if the agent is not already locked, it will suspend processing requests and return a SSH_AGENT_SUCCESS reply. If the agent is already locked, it will return SSH_AGENT_FAILURE. While locked, the agent will refuse all requests except SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are treated specially by a locked agent: it will always return an empty list of keys. To unlock an agent, a client may request: byte SSH_AGENTC_UNLOCK string passphrase If the passphrase matches and the agent is locked, then it will resume processing all requests and return SSH_AGENT_SUCCESS. If the agent is not locked or the passphrase does not match then it will return SSH_AGENT_FAILURE. Locking and unlocking affects both protocol 1 and protocol 2 keys. 3. Protocol message numbers 3.1 Requests from client to agent for protocol 1 key operations SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 SSH_AGENTC_RSA_CHALLENGE 3 SSH_AGENTC_ADD_RSA_IDENTITY 7 SSH_AGENTC_REMOVE_RSA_IDENTITY 8 SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 3.2 Requests from client to agent for protocol 2 key operations SSH2_AGENTC_REQUEST_IDENTITIES 11 SSH2_AGENTC_SIGN_REQUEST 13 SSH2_AGENTC_ADD_IDENTITY 17 SSH2_AGENTC_REMOVE_IDENTITY 18 SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 SSH2_AGENTC_ADD_ID_CONSTRAINED 25 3.3 Key-type independent requests from client to agent SSH_AGENTC_ADD_SMARTCARD_KEY 20 SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 SSH_AGENTC_LOCK 22 SSH_AGENTC_UNLOCK 23 SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 3.4 Generic replies from agent to client SSH_AGENT_FAILURE 5 SSH_AGENT_SUCCESS 6 3.5 Replies from agent to client for protocol 1 key operations SSH_AGENT_RSA_IDENTITIES_ANSWER 2 SSH_AGENT_RSA_RESPONSE 4 3.6 Replies from agent to client for protocol 2 key operations SSH2_AGENT_IDENTITIES_ANSWER 12 SSH2_AGENT_SIGN_RESPONSE 14 3.7 Key constraint identifiers SSH_AGENT_CONSTRAIN_LIFETIME 1 SSH_AGENT_CONSTRAIN_CONFIRM 2 $OpenBSD: PROTOCOL.agent,v 1.8 2015/05/08 03:56:51 djm Exp $ openssh-7.2p2/PROTOCOL.certkeys010064400017500001750000000247051267006270000144760ustar00djmdjmThis document describes a simple public-key certificate authentication system for use by SSH. Background ---------- The SSH protocol currently supports a simple public key authentication mechanism. Unlike other public key implementations, SSH eschews the use of X.509 certificates and uses raw keys. This approach has some benefits relating to simplicity of configuration and minimisation of attack surface, but it does not support the important use-cases of centrally managed, passwordless authentication and centrally certified host keys. These protocol extensions build on the simple public key authentication system already in SSH to allow certificate-based authentication. The certificates used are not traditional X.509 certificates, with numerous options and complex encoding rules, but something rather more minimal: a key, some identity information and usage options that have been signed with some other trusted key. A sshd server may be configured to allow authentication via certified keys, by extending the existing ~/.ssh/authorized_keys mechanism to allow specification of certification authority keys in addition to raw user keys. The ssh client will support automatic verification of acceptance of certified host keys, by adding a similar ability to specify CA keys in ~/.ssh/known_hosts. Certified keys are represented using new key types: ssh-rsa-cert-v01@openssh.com ssh-dss-cert-v01@openssh.com ecdsa-sha2-nistp256-cert-v01@openssh.com ecdsa-sha2-nistp384-cert-v01@openssh.com ecdsa-sha2-nistp521-cert-v01@openssh.com These include certification information along with the public key that is used to sign challenges. ssh-keygen performs the CA signing operation. Protocol extensions ------------------- The SSH wire protocol includes several extensibility mechanisms. These modifications shall take advantage of namespaced public key algorithm names to add support for certificate authentication without breaking the protocol - implementations that do not support the extensions will simply ignore them. Authentication using the new key formats described below proceeds using the existing SSH "publickey" authentication method described in RFC4252 section 7. New public key formats ---------------------- The certificate key types take a similar high-level format (note: data types and encoding are as per RFC4251 section 5). The serialised wire encoding of these certificates is also used for storing them on disk. #define SSH_CERT_TYPE_USER 1 #define SSH_CERT_TYPE_HOST 2 RSA certificate string "ssh-rsa-cert-v01@openssh.com" string nonce mpint e mpint n uint64 serial uint32 type string key id string valid principals uint64 valid after uint64 valid before string critical options string extensions string reserved string signature key string signature DSA certificate string "ssh-dss-cert-v01@openssh.com" string nonce mpint p mpint q mpint g mpint y uint64 serial uint32 type string key id string valid principals uint64 valid after uint64 valid before string critical options string extensions string reserved string signature key string signature ECDSA certificate string "ecdsa-sha2-nistp256@openssh.com" | "ecdsa-sha2-nistp384@openssh.com" | "ecdsa-sha2-nistp521@openssh.com" string nonce string curve string public_key uint64 serial uint32 type string key id string valid principals uint64 valid after uint64 valid before string critical options string extensions string reserved string signature key string signature The nonce field is a CA-provided random bitstring of arbitrary length (but typically 16 or 32 bytes) included to make attacks that depend on inducing collisions in the signature hash infeasible. e and n are the RSA exponent and public modulus respectively. p, q, g, y are the DSA parameters as described in FIPS-186-2. curve and public key are respectively the ECDSA "[identifier]" and "Q" defined in section 3.1 of RFC5656. serial is an optional certificate serial number set by the CA to provide an abbreviated way to refer to certificates from that CA. If a CA does not wish to number its certificates it must set this field to zero. type specifies whether this certificate is for identification of a user or a host using a SSH_CERT_TYPE_... value. key id is a free-form text field that is filled in by the CA at the time of signing; the intention is that the contents of this field are used to identify the identity principal in log messages. "valid principals" is a string containing zero or more principals as strings packed inside it. These principals list the names for which this certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and usernames for SSH_CERT_TYPE_USER certificates. As a special case, a zero-length "valid principals" field means the certificate is valid for any principal of the specified type. XXX DNS wildcards? "valid after" and "valid before" specify a validity period for the certificate. Each represents a time in seconds since 1970-01-01 00:00:00. A certificate is considered valid if: valid after <= current time < valid before criticial options is a set of zero or more key options encoded as below. All such options are "critical" in the sense that an implementation must refuse to authorise a key that has an unrecognised option. extensions is a set of zero or more optional extensions. These extensions are not critical, and an implementation that encounters one that it does not recognise may safely ignore it. Generally, critical options are used to control features that restrict access where extensions are used to enable features that grant access. This ensures that certificates containing unknown restrictions do not inadvertently grant access while allowing new protocol features to be enabled via extensions without breaking certificates' backwards compatibility. The reserved field is currently unused and is ignored in this version of the protocol. signature key contains the CA key used to sign the certificate. The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where the signature key type is a certificate type itself are NOT supported. Note that it is possible for a RSA certificate key to be signed by a DSS or ECDSA CA key and vice-versa. signature is computed over all preceding fields from the initial string up to, and including the signature key. Signatures are computed and encoded according to the rules defined for the CA's public key algorithm (RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA types). Critical options ---------------- The critical options section of the certificate specifies zero or more options on the certificates validity. The format of this field is a sequence of zero or more tuples: string name string data Options must be lexically ordered by "name" if they appear in the sequence. Each named option may only appear once in a certificate. The name field identifies the option and the data field encodes option-specific information (see below). All options are "critical", if an implementation does not recognise a option then the validating party should refuse to accept the certificate. The supported options and the contents and structure of their data fields are: Name Format Description ----------------------------------------------------------------------------- force-command string Specifies a command that is executed (replacing any the user specified on the ssh command-line) whenever this key is used for authentication. source-address string Comma-separated list of source addresses from which this certificate is accepted for authentication. Addresses are specified in CIDR format (nn.nn.nn.nn/nn or hhhh::hhhh/nn). If this option is not present then certificates may be presented from any source address. Extensions ---------- The extensions section of the certificate specifies zero or more non-critical certificate extensions. The encoding and ordering of extensions in this field is identical to that of the critical options, as is the requirement that each name appear only once. If an implementation does not recognise an extension, then it should ignore it. The supported extensions and the contents and structure of their data fields are: Name Format Description ----------------------------------------------------------------------------- permit-X11-forwarding empty Flag indicating that X11 forwarding should be permitted. X11 forwarding will be refused if this option is absent. permit-agent-forwarding empty Flag indicating that agent forwarding should be allowed. Agent forwarding must not be permitted unless this option is present. permit-port-forwarding empty Flag indicating that port-forwarding should be allowed. If this option is not present then no port forwarding will be allowed. permit-pty empty Flag indicating that PTY allocation should be permitted. In the absence of this option PTY allocation will be disabled. permit-user-rc empty Flag indicating that execution of ~/.ssh/rc should be permitted. Execution of this script will not be permitted if this option is not present. $OpenBSD: PROTOCOL.certkeys,v 1.9 2012/03/28 07:23:22 djm Exp $ openssh-7.2p2/PROTOCOL.chacha20poly1305010064400017500001750000000107141267006270000154260ustar00djmdjmThis document describes the chacha20-poly1305@openssh.com authenticated encryption cipher supported by OpenSSH. Background ---------- ChaCha20 is a stream cipher designed by Daniel Bernstein and described in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output is used as a keystream, with any unused bytes simply discarded. Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC that computes a 128 bit integrity tag given a message and a single-use 256 bit secret key. The chacha20-poly1305@openssh.com combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley in [3], but differs in the layout of data passed to the MAC and in the addition of encyption of the packet lengths. Negotiation ----------- The chacha20-poly1305@openssh.com offers both encryption and authentication. As such, no separate MAC is required. If the chacha20-poly1305@openssh.com cipher is selected in key exchange, the offered MAC algorithms are ignored and no MAC is required to be negotiated. Detailed Construction --------------------- The chacha20-poly1305@openssh.com cipher requires 512 bits of key material as output from the SSH key exchange. This forms two 256 bit keys (K_1 and K_2), used by two separate instances of chacha20. The instance keyed by K_1 is a stream cipher that is used only to encrypt the 4 byte packet length field. The second instance, keyed by K_2, is used in conjunction with poly1305 to build an AEAD (Authenticated Encryption with Associated Data) that is used to encrypt and authenticate the entire packet. Two separate cipher instances are used here so as to keep the packet lengths confidential but not create an oracle for the packet payload cipher by decrypting and using the packet length prior to checking the MAC. By using an independently-keyed cipher instance to encrypt the length, an active attacker seeking to exploit the packet input handling as a decryption oracle can learn nothing about the payload contents or its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). The AEAD is constructed as follows: for each packet, generate a Poly1305 key by taking the first 256 bits of ChaCha20 stream output generated using K_2, an IV consisting of the packet sequence number encoded as an uint64 under the SSH wire encoding rules and a ChaCha20 block counter of zero. The K_2 ChaCha20 block counter is then set to the little-endian encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used for encryption of the packet payload. Packet Handling --------------- When receiving a packet, the length must be decrypted first. When 4 bytes of ciphertext length have been received, they may be decrypted using the K_1 key, a nonce consisting of the packet sequence number encoded as a uint64 under the usual SSH wire encoding and a zero block counter to obtain the plaintext length. Once the entire packet has been received, the MAC MUST be checked before decryption. A per-packet Poly1305 key is generated as described above and the MAC tag calculated using Poly1305 with this key over the ciphertext of the packet length and the payload together. The calculated MAC is then compared in constant time with the one appended to the packet and the packet decrypted using ChaCha20 as described above (with K_2, the packet sequence number as nonce and a starting block counter of 1). To send a packet, first encode the 4 byte length and encrypt it using K_1. Encrypt the packet payload (using K_2) and append it to the encrypted length. Finally, calculate a MAC tag and append it. Rekeying -------- ChaCha20 must never reuse a {key, nonce} for encryption nor may it be used to encrypt more than 2^70 bytes under the same {key, nonce}. The SSH Transport protocol (RFC4253) recommends a far more conservative rekeying every 1GB of data sent or received. If this recommendation is followed, then chacha20-poly1305@openssh.com requires no special handling in this area. References ---------- [1] "ChaCha, a variant of Salsa20", Daniel Bernstein http://cr.yp.to/chacha/chacha-20080128.pdf [2] "The Poly1305-AES message-authentication code", Daniel Bernstein http://cr.yp.to/mac/poly1305-20050329.pdf [3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 $OpenBSD: PROTOCOL.chacha20poly1305,v 1.2 2013/12/02 02:50:27 djm Exp $ openssh-7.2p2/PROTOCOL.key010064400017500001750000000030031267006270000134210ustar00djmdjmThis document describes the private key format for OpenSSH. 1. Overall format The key consists of a header, a list of public keys, and an encrypted list of matching private keys. #define AUTH_MAGIC "openssh-key-v1" byte[] AUTH_MAGIC string ciphername string kdfname string kdfoptions int number of keys N string publickey1 string publickey2 ... string publickeyN string encrypted, padded list of private keys 2. KDF options for kdfname "bcrypt" The options: string salt uint32 rounds are concatenated and represented as a string. 3. Unencrypted list of N private keys The list of privatekey/comment pairs is padded with the bytes 1, 2, 3, ... until the total length is a multiple of the cipher block size. uint32 checkint uint32 checkint string privatekey1 string comment1 string privatekey2 string comment2 ... string privatekeyN string commentN char 1 char 2 char 3 ... char padlen % 255 Before the key is encrypted, a random integer is assigned to both checkint fields so successful decryption can be quickly checked by verifying that both checkint fields hold the same value. 4. Encryption The KDF is used to derive a key, IV (and other values required by the cipher) from the passphrase. These values are then used to encrypt the unencrypted list of private keys. 5. No encryption For unencrypted keys the cipher "none" and the KDF "none" are used with empty passphrases. The options if the KDF "none" are the empty string. $OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $ openssh-7.2p2/PROTOCOL.krl010064400017500001750000000120571267006270000134320ustar00djmdjmThis describes the key/certificate revocation list format for OpenSSH. 1. Overall format The KRL consists of a header and zero or more sections. The header is: #define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */ #define KRL_FORMAT_VERSION 1 uint64 KRL_MAGIC uint32 KRL_FORMAT_VERSION uint64 krl_version uint64 generated_date uint64 flags string reserved string comment Where "krl_version" is a version number that increases each time the KRL is modified, "generated_date" is the time in seconds since 1970-01-01 00:00:00 UTC that the KRL was generated, "comment" is an optional comment and "reserved" an extension field whose contents are currently ignored. No "flags" are currently defined. Following the header are zero or more sections, each consisting of: byte section_type string section_data Where "section_type" indicates the type of the "section_data". An exception to this is the KRL_SECTION_SIGNATURE section, that has a slightly different format (see below). The available section types are: #define KRL_SECTION_CERTIFICATES 1 #define KRL_SECTION_EXPLICIT_KEY 2 #define KRL_SECTION_FINGERPRINT_SHA1 3 #define KRL_SECTION_SIGNATURE 4 2. Certificate section These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by serial number or key ID. The consist of the CA key that issued the certificates to be revoked and a reserved field whose contents is currently ignored. string ca_key string reserved Where "ca_key" is the standard SSH wire serialisation of the CA's public key. Alternately, "ca_key" may be an empty string to indicate the certificate section applies to all CAs (this is most useful when revoking key IDs). Followed by one or more sections: byte cert_section_type string cert_section_data The certificate section types are: #define KRL_SECTION_CERT_SERIAL_LIST 0x20 #define KRL_SECTION_CERT_SERIAL_RANGE 0x21 #define KRL_SECTION_CERT_SERIAL_BITMAP 0x22 #define KRL_SECTION_CERT_KEY_ID 0x23 2.1 Certificate serial list section This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes certificates by listing their serial numbers. The cert_section_data in this case contains: uint64 revoked_cert_serial uint64 ... This section may appear multiple times. 2.2. Certificate serial range section These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold a range of serial numbers of certificates: uint64 serial_min uint64 serial_max All certificates in the range serial_min <= serial <= serial_max are revoked. This section may appear multiple times. 2.3. Certificate serial bitmap section Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys by listing their serial number in a bitmap. uint64 serial_offset mpint revoked_keys_bitmap A bit set at index N in the bitmap corresponds to revocation of a keys with serial number (serial_offset + N). This section may appear multiple times. 2.4. Revoked key ID sections KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key ID" strings. This may be useful in revoking all certificates associated with a particular identity, e.g. a host or a user. string key_id[0] ... This section must contain at least one "key_id". This section may appear multiple times. 3. Explicit key sections These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys (not certificates). They are less space efficient than serial numbers, but are able to revoke plain keys. string public_key_blob[0] .... This section must contain at least one "public_key_blob". The blob must be a raw key (i.e. not a certificate). This section may appear multiple times. 4. SHA1 fingerprint sections These sections, identified as KRL_SECTION_FINGERPRINT_SHA1, revoke plain keys (i.e. not certificates) by listing their SHA1 hashes: string public_key_hash[0] .... This section must contain at least one "public_key_hash". The hash blob is obtained by taking the SHA1 hash of the public key blob. Hashes in this section must appear in numeric order, treating each hash as a big- endian integer. This section may appear multiple times. 5. KRL signature sections The KRL_SECTION_SIGNATURE section serves a different purpose to the preceeding ones: to provide cryptographic authentication of a KRL that is retrieved over a channel that does not provide integrity protection. Its format is slightly different to the previously-described sections: in order to simplify the signature generation, it includes as a "body" two string components instead of one. byte KRL_SECTION_SIGNATURE string signature_key string signature The signature is calculated over the entire KRL from the KRL_MAGIC to this subsection's "signature_key", including both and using the signature generation rules appropriate for the type of "signature_key". This section must appear last in the KRL. If multiple signature sections appear, they must appear consecutively at the end of the KRL file. Implementations that retrieve KRLs over untrusted channels must verify signatures. Signature sections are optional for KRLs distributed by trusted means. $OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $ openssh-7.2p2/PROTOCOL.mux010064400017500001750000000141661267006270000134560ustar00djmdjmThis document describes the multiplexing protocol used by ssh(1)'s ControlMaster connection-sharing. Most messages from the client to the server contain a "request id" field. This field is returned in replies as "client request id" to facilitate matching of responses to requests. 1. Connection setup When a multiplexing connection is made to a ssh(1) operating as a ControlMaster from a ssh(1) in multiplex slave mode, the first action of each is to exchange hello messages: uint32 MUX_MSG_HELLO uint32 protocol version string extension name [optional] string extension value [optional] ... The current version of the mux protocol is 4. A slave should refuse to connect to a master that speaks an unsupported protocol version. Following the version identifier are zero or more extensions represented as a name/value pair. No extensions are currently defined. 2. Opening sessions To open a new multiplexed session, a client may send the following request: uint32 MUX_C_NEW_SESSION uint32 request id string reserved bool want tty flag bool want X11 forwarding flag bool want agent flag bool subsystem flag uint32 escape char string terminal type string command string environment string 0 [optional] ... To disable the use of an escape character, "escape char" may be set to 0xffffffff. "terminal type" is generally set to the value of $TERM. zero or more environment strings may follow the command. The client then sends its standard input, output and error file descriptors (in that order) using Unix domain socket control messages. The contents of "reserved" are currently ignored. If successful, the server will reply with MUX_S_SESSION_OPENED uint32 MUX_S_SESSION_OPENED uint32 client request id uint32 session id Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or MUX_S_FAILURE. Once the server has received the fds, it will respond with MUX_S_OK indicating that the session is up. The client now waits for the session to end. When it does, the server will send an exit status message: uint32 MUX_S_EXIT_MESSAGE uint32 session id uint32 exit value The client should exit with this value to mimic the behaviour of a non-multiplexed ssh(1) connection. Two additional cases that the client must cope with are it receiving a signal itself and the server disconnecting without sending an exit message. A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE if remote TTY allocation was unsuccessful. The client may use this to return its local tty to "cooked" mode. uint32 MUX_S_TTY_ALLOC_FAIL uint32 session id 3. Health checks The client may request a health check/PID report from a server: uint32 MUX_C_ALIVE_CHECK uint32 request id The server replies with: uint32 MUX_S_ALIVE uint32 client request id uint32 server pid 4. Remotely terminating a master A client may request that a master terminate immediately: uint32 MUX_C_TERMINATE uint32 request id The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED. 5. Requesting establishment of port forwards A client may request the master to establish a port forward: uint32 MUX_C_OPEN_FWD uint32 request id uint32 forwarding type string listen host uint32 listen port string connect host uint32 connect port forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. If listen port is (unsigned int) -2, then the listen host is treated as a unix socket path name. If connect port is (unsigned int) -2, then the connect host is treated as a unix socket path name. A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. For dynamically allocated listen port the server replies with uint32 MUX_S_REMOTE_PORT uint32 client request id uint32 allocated remote listen port 6. Requesting closure of port forwards Note: currently unimplemented (server will always reply with MUX_S_FAILURE). A client may request the master to close a port forward: uint32 MUX_C_CLOSE_FWD uint32 request id uint32 forwarding type string listen host uint32 listen port string connect host uint32 connect port A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. 7. Requesting stdio forwarding A client may request the master to establish a stdio forwarding: uint32 MUX_C_NEW_STDIO_FWD uint32 request id string reserved string connect host string connect port The client then sends its standard input and output file descriptors (in that order) using Unix domain socket control messages. The contents of "reserved" are currently ignored. A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. 8. Requesting shutdown of mux listener A client may request the master to stop accepting new multiplexing requests and remove its listener socket. uint32 MUX_C_STOP_LISTENING uint32 request id A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. 9. Status messages The MUX_S_OK message is empty: uint32 MUX_S_OK uint32 client request id The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: uint32 MUX_S_PERMISSION_DENIED uint32 client request id string reason uint32 MUX_S_FAILURE uint32 client request id string reason 10. Protocol numbers #define MUX_MSG_HELLO 0x00000001 #define MUX_C_NEW_SESSION 0x10000002 #define MUX_C_ALIVE_CHECK 0x10000004 #define MUX_C_TERMINATE 0x10000005 #define MUX_C_OPEN_FWD 0x10000006 #define MUX_C_CLOSE_FWD 0x10000007 #define MUX_C_NEW_STDIO_FWD 0x10000008 #define MUX_C_STOP_LISTENING 0x10000009 #define MUX_S_OK 0x80000001 #define MUX_S_PERMISSION_DENIED 0x80000002 #define MUX_S_FAILURE 0x80000003 #define MUX_S_EXIT_MESSAGE 0x80000004 #define MUX_S_ALIVE 0x80000005 #define MUX_S_SESSION_OPENED 0x80000006 #define MUX_S_REMOTE_PORT 0x80000007 #define MUX_S_TTY_ALLOC_FAIL 0x80000008 #define MUX_FWD_LOCAL 1 #define MUX_FWD_REMOTE 2 #define MUX_FWD_DYNAMIC 3 XXX TODO XXX extended status (e.g. report open channels / forwards) XXX lock (maybe) XXX watch in/out traffic (pre/post crypto) XXX inject packet (what about replies) XXX server->client error/warning notifications XXX send signals via mux $OpenBSD: PROTOCOL.mux,v 1.10 2015/07/17 03:04:27 djm Exp $ openssh-7.2p2/README010064400017500001750000000055031267006270000123350ustar00djmdjmSee http://www.openssh.com/txt/release-7.2p2 for the release notes. Please read http://www.openssh.com/report.html for bug reporting instructions and note that we do not use Github for bug reporting or patch/pull-request management. - 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 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 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.87 2014/08/10 01:35:06 djm Exp $ openssh-7.2p2/README.dns010064400017500001750000000031071267006270000131160ustar00djmdjmHow 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 $ openssh-7.2p2/README.platform010064400017500001750000000100171267006270000141540ustar00djmdjmThis 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 If you wish to use dynamic libraries that aren't in the normal system locations (eg IBM's OpenSSL and zlib packages) then you will need to define the environment variable blibpath before running configure, eg blibpath=/lib:/usr/lib:/opt/freeware/lib ./configure \ --with-ssl-dir=/opt/freeware --with-zlib=/opt/freeware If sshd is built with the WITH_AIXAUTHENTICATE option (which is enabled by default) then sshd checks that users are permitted via the loginrestrictions() function, in particular that the user has the "rlogin" attribute set. This check is not done for the root account, instead the PermitRootLogin setting in sshd_config is used. If you are using the IBM compiler you probably want to use CC=xlc rather than the default of cc. 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/ Linux ----- Some Linux distributions (including Red Hat/Fedora/CentOS) include headers and library links in the -devel RPMs rather than the main binary RPMs. If you get an error about headers, or complaining about a missing prerequisite then you may need to install the equivalent development packages. On Redhat based distros these may be openssl-devel, zlib-devel and pam-devel, on Debian based distros these may be libssl-dev, libz-dev and libpam-dev. 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.10 2009/08/28 23:14:48 dtucker Exp $ openssh-7.2p2/README.privsep010064400017500001750000000051471267006270000140300ustar00djmdjmPrivilege 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 $ openssh-7.2p2/README.tun010064400017500001750000000114321267006270000131400ustar00djmdjmHow 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 $ openssh-7.2p2/TODO010064400017500001750000000053251267006270000121470ustar00djmdjmDocumentation: - 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 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 $ openssh-7.2p2/aclocal.m4010064400017500001750000000125451267006270000133210ustar00djmdjmdnl $Id: aclocal.m4,v 1.13 2014/01/22 10:30:12 djm Exp $ dnl dnl OpenSSH-specific autoconf macros dnl dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag]) dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ AC_MSG_CHECKING([if $CC supports compile flag $1]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" test "x$_define_flag" = "x" && _define_flag="$1" AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } ]])], [ if `grep -i "unrecognized option" conftest.err >/dev/null` then AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" else AC_MSG_RESULT([yes]) CFLAGS="$saved_CFLAGS $_define_flag" fi], [ AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" ] ) }]) dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag]) dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" test "x$_define_flag" = "x" && _define_flag="$1" AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } ]])], [ if `grep -i "unrecognized option" conftest.err >/dev/null` then AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" else AC_MSG_RESULT([yes]) CFLAGS="$saved_CFLAGS $_define_flag" fi], [ AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" ] ) }]) dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag]) dnl Check that $LD accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ AC_MSG_CHECKING([if $LD supports link flag $1]) saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR $1" _define_flag="$2" test "x$_define_flag" = "x" && _define_flag="$1" AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } ]])], [ AC_MSG_RESULT([yes]) LDFLAGS="$saved_LDFLAGS $_define_flag"], [ AC_MSG_RESULT([no]) LDFLAGS="$saved_LDFLAGS" ] ) }]) 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 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 #include 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 #include ]) ]) openssh-7.2p2/addrmatch.c010064400017500001750000000256531267006270000135600ustar00djmdjm/* $OpenBSD: addrmatch.c,v 1.10 2015/07/08 19:04:21 markus Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #include #include #include #include #include #include #include #include #include "match.h" #include "log.h" struct xaddr { sa_family_t af; union { struct in_addr v4; struct in6_addr v6; u_int8_t addr8[16]; u_int32_t addr32[4]; } xa; /* 128-bit address */ u_int32_t scope_id; /* iface scope id for v6 */ #define v4 xa.v4 #define v6 xa.v6 #define addr8 xa.addr8 #define addr32 xa.addr32 }; static int addr_unicast_masklen(int af) { switch (af) { case AF_INET: return 32; case AF_INET6: return 128; default: return -1; } } static inline int masklen_valid(int af, u_int masklen) { switch (af) { case AF_INET: return masklen <= 32 ? 0 : -1; case AF_INET6: return masklen <= 128 ? 0 : -1; default: return -1; } } /* * Convert struct sockaddr to struct xaddr * Returns 0 on success, -1 on failure. */ static int addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) { struct sockaddr_in *in4 = (struct sockaddr_in *)sa; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; memset(xa, '\0', sizeof(*xa)); switch (sa->sa_family) { case AF_INET: if (slen < (socklen_t)sizeof(*in4)) return -1; xa->af = AF_INET; memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); break; case AF_INET6: if (slen < (socklen_t)sizeof(*in6)) return -1; xa->af = AF_INET6; memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID xa->scope_id = in6->sin6_scope_id; #endif break; default: return -1; } return 0; } /* * Calculate a netmask of length 'l' for address family 'af' and * store it in 'n'. * Returns 0 on success, -1 on failure. */ static int addr_netmask(int af, u_int l, struct xaddr *n) { int i; if (masklen_valid(af, l) != 0 || n == NULL) return -1; memset(n, '\0', sizeof(*n)); switch (af) { case AF_INET: n->af = AF_INET; if (l == 0) return 0; n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); return 0; case AF_INET6: n->af = AF_INET6; for (i = 0; i < 4 && l >= 32; i++, l -= 32) n->addr32[i] = 0xffffffffU; if (i < 4 && l != 0) n->addr32[i] = htonl((0xffffffff << (32 - l)) & 0xffffffff); return 0; default: return -1; } } /* * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'. * Returns 0 on success, -1 on failure. */ static int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) { int i; if (dst == NULL || a == NULL || b == NULL || a->af != b->af) return -1; memcpy(dst, a, sizeof(*dst)); switch (a->af) { case AF_INET: dst->v4.s_addr &= b->v4.s_addr; return 0; case AF_INET6: dst->scope_id = a->scope_id; for (i = 0; i < 4; i++) dst->addr32[i] &= b->addr32[i]; return 0; default: return -1; } } /* * Compare addresses 'a' and 'b' * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b) */ static int addr_cmp(const struct xaddr *a, const struct xaddr *b) { int i; if (a->af != b->af) return a->af == AF_INET6 ? 1 : -1; switch (a->af) { case AF_INET: if (a->v4.s_addr == b->v4.s_addr) return 0; return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1; case AF_INET6: for (i = 0; i < 16; i++) if (a->addr8[i] - b->addr8[i] != 0) return a->addr8[i] > b->addr8[i] ? 1 : -1; if (a->scope_id == b->scope_id) return 0; return a->scope_id > b->scope_id ? 1 : -1; default: return -1; } } /* * Parse string address 'p' into 'n' * Returns 0 on success, -1 on failure. */ static int addr_pton(const char *p, struct xaddr *n) { struct addrinfo hints, *ai; memset(&hints, '\0', sizeof(hints)); hints.ai_flags = AI_NUMERICHOST; if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) return -1; if (ai == NULL || ai->ai_addr == NULL) return -1; if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) { freeaddrinfo(ai); return -1; } freeaddrinfo(ai); return 0; } /* * Perform bitwise negation of address * Returns 0 on success, -1 on failure. */ static int addr_invert(struct xaddr *n) { int i; if (n == NULL) return (-1); switch (n->af) { case AF_INET: n->v4.s_addr = ~n->v4.s_addr; return (0); case AF_INET6: for (i = 0; i < 4; i++) n->addr32[i] = ~n->addr32[i]; return (0); default: return (-1); } } /* * Calculate a netmask of length 'l' for address family 'af' and * store it in 'n'. * Returns 0 on success, -1 on failure. */ static int addr_hostmask(int af, u_int l, struct xaddr *n) { if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) return (-1); return (0); } /* * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::) * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure. */ static int addr_is_all0s(const struct xaddr *a) { int i; switch (a->af) { case AF_INET: return (a->v4.s_addr == 0 ? 0 : -1); case AF_INET6:; for (i = 0; i < 4; i++) if (a->addr32[i] != 0) return (-1); return (0); default: return (-1); } } /* * Test whether host portion of address 'a', as determined by 'masklen' * is all zeros. * Returns 0 on if host portion of address is all-zeros, * -1 if not all zeros or on failure. */ static int addr_host_is_all0s(const struct xaddr *a, u_int masklen) { struct xaddr tmp_addr, tmp_mask, tmp_result; memcpy(&tmp_addr, a, sizeof(tmp_addr)); if (addr_hostmask(a->af, masklen, &tmp_mask) == -1) return (-1); if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1) return (-1); return (addr_is_all0s(&tmp_result)); } /* * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). * Return -1 on parse error, -2 on inconsistency or 0 on success. */ static int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) { struct xaddr tmp; long unsigned int masklen = 999; char addrbuf[64], *mp, *cp; /* Don't modify argument */ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf)) return -1; if ((mp = strchr(addrbuf, '/')) != NULL) { *mp = '\0'; mp++; masklen = strtoul(mp, &cp, 10); if (*mp == '\0' || *cp != '\0' || masklen > 128) return -1; } if (addr_pton(addrbuf, &tmp) == -1) return -1; if (mp == NULL) masklen = addr_unicast_masklen(tmp.af); if (masklen_valid(tmp.af, masklen) == -1) return -2; if (addr_host_is_all0s(&tmp, masklen) != 0) return -2; if (n != NULL) memcpy(n, &tmp, sizeof(*n)); if (l != NULL) *l = masklen; return 0; } static int addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) { struct xaddr tmp_mask, tmp_result; if (host->af != net->af) return -1; if (addr_netmask(host->af, masklen, &tmp_mask) == -1) return -1; if (addr_and(&tmp_result, host, &tmp_mask) == -1) return -1; return addr_cmp(&tmp_result, net); } /* * Match "addr" against list pattern list "_list", which may contain a * mix of CIDR addresses and old-school wildcards. * * If addr is NULL, then no matching is performed, but _list is parsed * and checked for well-formedness. * * Returns 1 on match found (never returned when addr == NULL). * Returns 0 on if no match found, or no errors found when addr == NULL. * Returns -1 on negated match found (never returned when addr == NULL). * Returns -2 on invalid list entry. */ int addr_match_list(const char *addr, const char *_list) { char *list, *cp, *o; struct xaddr try_addr, match_addr; u_int masklen, neg; int ret = 0, r; if (addr != NULL && addr_pton(addr, &try_addr) != 0) { debug2("%s: couldn't parse address %.100s", __func__, addr); return 0; } if ((o = list = strdup(_list)) == NULL) return -1; while ((cp = strsep(&list, ",")) != NULL) { neg = *cp == '!'; if (neg) cp++; if (*cp == '\0') { ret = -2; break; } /* Prefer CIDR address matching */ r = addr_pton_cidr(cp, &match_addr, &masklen); if (r == -2) { error("Inconsistent mask length for " "network \"%.100s\"", cp); ret = -2; break; } else if (r == 0) { if (addr != NULL && addr_netmatch(&try_addr, &match_addr, masklen) == 0) { foundit: if (neg) { ret = -1; break; } ret = 1; } continue; } else { /* If CIDR parse failed, try wildcard string match */ if (addr != NULL && match_pattern(addr, cp) == 1) goto foundit; } } free(o); return ret; } /* * Match "addr" against list CIDR list "_list". Lexical wildcards and * negation are not supported. If "addr" == NULL, will verify structure * of "_list". * * Returns 1 on match found (never returned when addr == NULL). * Returns 0 on if no match found, or no errors found when addr == NULL. * Returns -1 on error */ int addr_match_cidr_list(const char *addr, const char *_list) { char *list, *cp, *o; struct xaddr try_addr, match_addr; u_int masklen; int ret = 0, r; if (addr != NULL && addr_pton(addr, &try_addr) != 0) { debug2("%s: couldn't parse address %.100s", __func__, addr); return 0; } if ((o = list = strdup(_list)) == NULL) return -1; while ((cp = strsep(&list, ",")) != NULL) { if (*cp == '\0') { error("%s: empty entry in list \"%.100s\"", __func__, o); ret = -1; break; } /* * NB. This function is called in pre-auth with untrusted data, * so be extra paranoid about junk reaching getaddrino (via * addr_pton_cidr). */ /* Stop junk from reaching getaddrinfo. +3 is for masklen */ if (strlen(cp) > INET6_ADDRSTRLEN + 3) { error("%s: list entry \"%.100s\" too long", __func__, cp); ret = -1; break; } #define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/" if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) { error("%s: list entry \"%.100s\" contains invalid " "characters", __func__, cp); ret = -1; } /* Prefer CIDR address matching */ r = addr_pton_cidr(cp, &match_addr, &masklen); if (r == -1) { error("Invalid network entry \"%.100s\"", cp); ret = -1; break; } else if (r == -2) { error("Inconsistent mask length for " "network \"%.100s\"", cp); ret = -1; break; } else if (r == 0 && addr != NULL) { if (addr_netmatch(&try_addr, &match_addr, masklen) == 0) ret = 1; continue; } } free(o); return ret; } openssh-7.2p2/atomicio.c010064400017500001750000000106061267006270000134250ustar00djmdjm/* $OpenBSD: atomicio.c,v 1.27 2015/01/16 06:40:12 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 #include #include #ifdef HAVE_POLL_H #include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif #include #include #include #include "atomicio.h" /* * ensure all of data on socket comes through. f==read || f==vwrite */ size_t atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, int (*cb)(void *, size_t), void *cb_arg) { char *s = _s; size_t pos = 0; ssize_t res; struct pollfd pfd; #ifndef BROKEN_READ_COMPARISON pfd.fd = fd; pfd.events = f == read ? POLLIN : POLLOUT; #endif while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: if (errno == EINTR) continue; if (errno == EAGAIN || errno == EWOULDBLOCK) { #ifndef BROKEN_READ_COMPARISON (void)poll(&pfd, 1, -1); #endif continue; } return 0; case 0: errno = EPIPE; return pos; default: pos += (size_t)res; if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { errno = EINTR; return pos; } } } return pos; } size_t atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) { return atomicio6(f, fd, _s, n, NULL, NULL); } /* * ensure all of data on socket comes through. f==readv || f==writev */ size_t atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *cb_arg) { size_t pos = 0, rem; ssize_t res; struct iovec iov_array[IOV_MAX], *iov = iov_array; struct pollfd pfd; if (iovcnt > IOV_MAX) { errno = EINVAL; return 0; } /* Make a copy of the iov array because we may modify it below */ memcpy(iov, _iov, iovcnt * sizeof(*_iov)); #ifndef BROKEN_READV_COMPARISON pfd.fd = fd; pfd.events = f == readv ? POLLIN : POLLOUT; #endif for (; iovcnt > 0 && iov[0].iov_len > 0;) { res = (f) (fd, iov, iovcnt); switch (res) { case -1: if (errno == EINTR) continue; if (errno == EAGAIN || errno == EWOULDBLOCK) { #ifndef BROKEN_READV_COMPARISON (void)poll(&pfd, 1, -1); #endif 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; } if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { errno = EINTR; return pos; } } return pos; } size_t atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, const struct iovec *_iov, int iovcnt) { return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL); } openssh-7.2p2/atomicio.h010064400017500001750000000042141267006270000134300ustar00djmdjm/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm 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 atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, int (*cb)(void *, size_t), void *); 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 atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *); size_t atomiciov(ssize_t (*)(int, const struct iovec *, int), int, const struct iovec *, int); #endif /* _ATOMICIO_H */ openssh-7.2p2/audit-bsm.c010064400017500001750000000276261267006270000135200ustar00djmdjm/* $Id: audit-bsm.c,v 1.8 2012/02/23 23:40:43 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 #include #include #include #include #include #ifdef BROKEN_BSM_API #include #endif #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 #include #include #include #include #if defined(HAVE_GETAUDIT_ADDR) #define AuditInfoStruct auditinfo_addr #define AuditInfoTermID au_tid_addr_t #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 SetAuditFunc(a,b) setaudit(a) #define SetAuditFuncText "setaudit" #define AUToSubjectFunc au_to_subject #define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b)) #endif #ifndef cannot_audit extern int cannot_audit(int); #endif extern void aug_init(void); extern 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; #ifdef BROKEN_BSM_API /* For some reason this constant is no longer defined in Solaris 11. */ #define BSM_TEXTBUFSZ 256 #endif /* Below is the low-level BSM interface code */ /* * aug_get_machine is only required on IPv6 capable machines, we use a * different mechanism in audit_connection_from() for IPv4-only machines. * getaudit_addr() is only present on IPv6 capable machines. */ #if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR) extern int aug_get_machine(char *, u_int32_t *, u_int32_t *); #else static int aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type) { struct addrinfo *ai; struct sockaddr_in *in4; struct sockaddr_in6 *in6; int ret = 0, r; if ((r = getaddrinfo(host, NULL, NULL, &ai)) != 0) { error("BSM audit: getaddrinfo failed for %.100s: %.100s", host, r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); return -1; } switch (ai->ai_family) { case AF_INET: in4 = (struct sockaddr_in *)ai->ai_addr; *type = AU_IPv4; memcpy(addr, &in4->sin_addr, sizeof(struct in_addr)); break; #ifdef AU_IPv6 case AF_INET6: in6 = (struct sockaddr_in6 *)ai->ai_addr; *type = AU_IPv6; memcpy(addr, &in6->sin6_addr, sizeof(struct in6_addr)); break; #endif default: error("BSM audit: unknown address family for %.100s: %d", host, ai->ai_family); ret = -1; } freeaddrinfo(ai); return ret; } #endif #ifdef BROKEN_BSM_API /* In Solaris 11 the audit daemon has been moved to SMF. In the process they simply dropped getacna() from the API, since it read from a now non-existent config file. This function re-implements getacna() to read from the SMF repository instead. */ int getacna(char *auditstring, int len) { scf_handle_t *handle = NULL; scf_property_t *property = NULL; scf_value_t *value = NULL; int ret = 0; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) return -2; /* The man page for getacna on Solaris 10 states we should return -2 in case of error and set errno to indicate the error. We don't bother with errno here, though, since the only use of this function below doesn't check for errors anyway. */ ret = scf_handle_bind(handle); if (ret == -1) return -2; property = scf_property_create(handle); if (property == NULL) return -2; ret = scf_handle_decode_fmri(handle, "svc:/system/auditd:default/:properties/preselection/naflags", NULL, NULL, NULL, NULL, property, 0); if (ret == -1) return -2; value = scf_value_create(handle); if (value == NULL) return -2; ret = scf_property_get_value(property, value); if (ret == -1) return -2; ret = scf_value_get_astring(value, auditstring, len); if (ret == -1) return -2; scf_value_destroy(value); scf_property_destroy(property); scf_handle_destroy(handle); return 0; } #endif /* * Check if the specified event is selected (enabled) for auditing. * Returns 1 if the event is selected, 0 if not and -1 on failure. */ 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)); #ifdef BROKEN_BSM_API /* The last argument is the event modifier flags. For some seemingly undocumented reason it was added in Solaris 11. */ rc = au_close(ad, AU_TO_WRITE, event_no, 0); #else rc = au_close(ad, AU_TO_WRITE, event_no); #endif 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(struct logininfo *li) { /* not implemented */ } void audit_session_close(struct logininfo *li) { /* 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 */ openssh-7.2p2/audit-linux.c010064400017500001750000000067311267006270000140700ustar00djmdjm/* $Id: audit-linux.c,v 1.1 2011/01/17 10:15:30 dtucker Exp $ */ /* * Copyright 2010 Red Hat, 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. * * Red Hat author: Jan F. Chadima */ #include "includes.h" #if defined(USE_LINUX_AUDIT) #include #include #include #include "log.h" #include "audit.h" #include "canohost.h" const char* audit_username(void); int linux_audit_record_event(int uid, const char *username, const char *hostname, const char *ip, const char *ttyn, int success) { int audit_fd, rc, saved_errno; audit_fd = audit_open(); if (audit_fd < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) return 1; /* No audit support in kernel */ else return 0; /* Must prevent login */ } rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); saved_errno = errno; close(audit_fd); /* * Do not report error if the error is EPERM and sshd is run as non * root user. */ if ((rc == -EPERM) && (geteuid() != 0)) rc = 0; errno = saved_errno; return (rc >= 0); } /* Below is the sshd audit API code */ void audit_connection_from(const char *host, int port) { } /* not implemented */ void audit_run_command(const char *command) { /* not implemented */ } void audit_session_open(struct logininfo *li) { if (linux_audit_record_event(li->uid, NULL, li->hostname, NULL, li->line, 1) == 0) fatal("linux_audit_write_entry failed: %s", strerror(errno)); } void audit_session_close(struct logininfo *li) { /* not implemented */ } void audit_event(ssh_audit_event_t event) { switch(event) { case SSH_AUTH_SUCCESS: case SSH_CONNECTION_CLOSE: case SSH_NOLOGIN: case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_LOGIN_ROOT_DENIED: break; case SSH_AUTH_FAIL_NONE: case SSH_AUTH_FAIL_PASSWD: case SSH_AUTH_FAIL_KBDINT: case SSH_AUTH_FAIL_PUBKEY: case SSH_AUTH_FAIL_HOSTBASED: case SSH_AUTH_FAIL_GSSAPI: case SSH_INVALID_USER: linux_audit_record_event(-1, audit_username(), NULL, get_remote_ipaddr(), "sshd", 0); break; default: debug("%s: unhandled event %d", __func__, event); } } #endif /* USE_LINUX_AUDIT */ openssh-7.2p2/audit.c010064400017500001750000000133741267006270000127340ustar00djmdjm/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */ /* * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #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(struct logininfo *li) { const char *t = li->line ? li->line : "(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(struct logininfo *li) { const char *t = li->line ? li->line : "(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 */ openssh-7.2p2/audit.h010064400017500001750000000045221267006270000127340ustar00djmdjm/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 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 #include "loginrec.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(struct logininfo *); void audit_session_close(struct logininfo *); void audit_run_command(const char *); ssh_audit_event_t audit_classify_auth(const char *); #endif /* _SSH_AUDIT_H */ openssh-7.2p2/auth-bsdauth.c010064400017500001750000000072211267006270000142110ustar00djmdjm/* $OpenBSD: auth-bsdauth.c,v 1.14 2015/10/20 23:24:25 mmcc 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 #include #include #include #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; *infotxt = NULL; *numprompts = 0; *prompts = NULL; *echo_on = 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 : ""); 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 == NULL) 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 openssh-7.2p2/auth-chall.c010064400017500001750000000071101267006270000136370ustar00djmdjm/* $OpenBSD: auth-chall.c,v 1.14 2014/06/24 01:13:21 djm 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 #include #include #include #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "log.h" #include "misc.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++) free(prompts[i]); free(prompts); free(name); free(echo_on); free(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++) free(prompts[i]); free(prompts); free(name); free(echo_on); free(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; } } openssh-7.2p2/auth-krb5.c010064400017500001750000000157061267006270000134310ustar00djmdjm/* $OpenBSD: auth-krb5.c,v 1.21 2016/01/27 06:44:58 djm Exp $ */ /* * Kerberos v5 authentication and ticket-passing routines. * * From: FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar */ /* * 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 #include #include #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "packet.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.h" #include "uidswap.h" #include "key.h" #include "hostfile.h" #include "auth.h" #ifdef KRB5 #include #include #include #include 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; char *client, *platform_client; const char *errmsg; /* get platform-specific kerberos client principal name (if it exists) */ platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name); client = platform_client ? platform_client : authctxt->pw->pw_name; temporarily_use_uid(authctxt->pw); problem = krb5_init(authctxt); if (problem) goto out; problem = krb5_parse_name(authctxt->krb5_ctx, client, &authctxt->krb5_user); if (problem) goto out; #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE problem = krb5_cc_new_unique(authctxt->krb5_ctx, krb5_mcc_ops.prefix, NULL, &ccache); # else problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); # endif 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; # ifdef HAVE_KRB5_CC_NEW_UNIQUE problem = krb5_cc_new_unique(authctxt->krb5_ctx, krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache); # else problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &authctxt->krb5_fwd_ccache); # endif 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(); free(platform_client); if (problem) { if (ccache) krb5_cc_destroy(authctxt->krb5_ctx, ccache); if (authctxt->krb5_ctx != NULL && problem!=-1) { errmsg = krb5_get_error_message(authctxt->krb5_ctx, problem); debug("Kerberos password authentication failed: %s", errmsg); krb5_free_error_message(authctxt->krb5_ctx, errmsg); } 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, oerrno; 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:")); oerrno = errno; umask(old_umask); if (tmpfd == -1) { logit("mkstemp(): %.100s", strerror(oerrno)); return oerrno; } if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { oerrno = errno; logit("fchmod(): %.100s", strerror(oerrno)); close(tmpfd); return oerrno; } close(tmpfd); return (krb5_cc_resolve(ctx, ccname, ccache)); } #endif /* !HEIMDAL */ #endif /* KRB5 */ openssh-7.2p2/auth-options.c010064400017500001750000000401261267006270000142530ustar00djmdjm/* $OpenBSD: auth-options.c,v 1.70 2015/12/10 17:08:40 mmcc Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "key.h" /* XXX for typedef */ #include "buffer.h" /* XXX for typedef */ #include "xmalloc.h" #include "match.h" #include "ssherr.h" #include "log.h" #include "canohost.h" #include "sshbuf.h" #include "misc.h" #include "channels.h" #include "servconf.h" #include "sshkey.h" #include "auth-options.h" #include "hostfile.h" #include "auth.h" /* Flags set authorized_keys flags */ int no_port_forwarding_flag = 0; int no_agent_forwarding_flag = 0; int no_x11_forwarding_flag = 0; int no_pty_flag = 0; int no_user_rc = 0; int key_is_cert_authority = 0; /* "command=" option. */ char *forced_command = NULL; /* "environment=" options. */ struct envstring *custom_environment = NULL; /* "tunnel=" option. */ int forced_tun_device = -1; /* "principals=" option. */ char *authorized_principals = NULL; extern ServerOptions options; void auth_clear_options(void) { no_agent_forwarding_flag = 0; no_port_forwarding_flag = 0; no_pty_flag = 0; no_x11_forwarding_flag = 0; no_user_rc = 0; key_is_cert_authority = 0; while (custom_environment) { struct envstring *ce = custom_environment; custom_environment = ce->next; free(ce->s); free(ce); } free(forced_command); forced_command = NULL; free(authorized_principals); authorized_principals = NULL; forced_tun_device = -1; channel_clear_permitted_opens(); } /* * Match flag 'opt' in *optsp, and if allow_negate is set then also match * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 * if negated option matches. * If the option or negated option matches, then *optsp is updated to * point to the first character after the option and, if 'msg' is not NULL * then a message based on it added via auth_debug_add(). */ static int match_flag(const char *opt, int allow_negate, char **optsp, const char *msg) { size_t opt_len = strlen(opt); char *opts = *optsp; int negate = 0; if (allow_negate && strncasecmp(opts, "no-", 3) == 0) { opts += 3; negate = 1; } if (strncasecmp(opts, opt, opt_len) == 0) { *optsp = opts + opt_len; if (msg != NULL) { auth_debug_add("%s %s.", msg, negate ? "disabled" : "enabled"); } return negate ? 0 : 1; } return -1; } /* * 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, r; /* reset options */ auth_clear_options(); if (!opts) return 1; while (*opts && *opts != ' ' && *opts != '\t') { if ((r = match_flag("cert-authority", 0, &opts, NULL)) != -1) { key_is_cert_authority = r; goto next_option; } if ((r = match_flag("restrict", 0, &opts, NULL)) != -1) { auth_debug_add("Key is restricted."); no_port_forwarding_flag = 1; no_agent_forwarding_flag = 1; no_x11_forwarding_flag = 1; no_pty_flag = 1; no_user_rc = 1; goto next_option; } if ((r = match_flag("port-forwarding", 1, &opts, "Port forwarding")) != -1) { no_port_forwarding_flag = r != 1; goto next_option; } if ((r = match_flag("agent-forwarding", 1, &opts, "Agent forwarding")) != -1) { no_agent_forwarding_flag = r != 1; goto next_option; } if ((r = match_flag("x11-forwarding", 1, &opts, "X11 forwarding")) != -1) { no_x11_forwarding_flag = r != 1; goto next_option; } if ((r = match_flag("pty", 1, &opts, "PTY allocation")) != -1) { no_pty_flag = r != 1; goto next_option; } if ((r = match_flag("user-rc", 1, &opts, "User rc execution")) != -1) { no_user_rc = r != 1; goto next_option; } cp = "command=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { opts += strlen(cp); free(forced_command); 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); free(forced_command); forced_command = NULL; goto bad_option; } forced_command[i] = '\0'; auth_debug_add("Forced command."); opts++; goto next_option; } cp = "principals=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { opts += strlen(cp); free(authorized_principals); authorized_principals = xmalloc(strlen(opts) + 1); i = 0; while (*opts) { if (*opts == '"') break; if (*opts == '\\' && opts[1] == '"') { opts += 2; authorized_principals[i++] = '"'; continue; } authorized_principals[i++] = *opts++; } if (!*opts) { debug("%.100s, line %lu: missing end quote", file, linenum); auth_debug_add("%.100s, line %lu: missing end quote", file, linenum); free(authorized_principals); authorized_principals = NULL; goto bad_option; } authorized_principals[i] = '\0'; auth_debug_add("principals: %.900s", authorized_principals); opts++; goto next_option; } cp = "environment=\""; if (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); free(s); goto bad_option; } s[i] = '\0'; opts++; if (options.permit_user_env) { auth_debug_add("Adding to environment: " "%.900s", s); debug("Adding to environment: %.900s", s); new_envstring = xcalloc(1, sizeof(*new_envstring)); new_envstring->s = s; new_envstring->next = custom_environment; custom_environment = new_envstring; s = NULL; } free(s); 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); free(patterns); goto bad_option; } patterns[i] = '\0'; opts++; switch (match_host_and_ip(remote_host, remote_ip, patterns)) { case 1: free(patterns); /* Host name matches. */ goto next_option; case -1: debug("%.100s, line %lu: invalid criteria", file, linenum); auth_debug_add("%.100s, line %lu: " "invalid criteria", file, linenum); /* FALLTHROUGH */ case 0: free(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); break; } /* deny access */ return 0; } cp = "permitopen=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { char *host, *p; int 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); free(patterns); goto bad_option; } patterns[i] = '\0'; opts++; p = patterns; /* XXX - add streamlocal support */ 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); free(patterns); goto bad_option; } host = cleanhostname(host); if (p == NULL || (port = permitopen_port(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); free(patterns); goto bad_option; } if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) channel_add_permitted_opens(host, port); free(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); free(tun); forced_tun_device = -1; goto bad_option; } tun[i] = '\0'; forced_tun_device = a2tun(tun, NULL); free(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. */ } /* 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); /* deny access */ return 0; } #define OPTIONS_CRITICAL 1 #define OPTIONS_EXTENSIONS 2 static int parse_option_list(struct sshbuf *oblob, struct passwd *pw, u_int which, int crit, int *cert_no_port_forwarding_flag, int *cert_no_agent_forwarding_flag, int *cert_no_x11_forwarding_flag, int *cert_no_pty_flag, int *cert_no_user_rc, char **cert_forced_command, int *cert_source_address_done) { char *command, *allowed; const char *remote_ip; char *name = NULL; struct sshbuf *c = NULL, *data = NULL; int r, ret = -1, result, found; if ((c = sshbuf_fromb(oblob)) == NULL) { error("%s: sshbuf_fromb failed", __func__); goto out; } while (sshbuf_len(c) > 0) { sshbuf_free(data); data = NULL; if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 || (r = sshbuf_froms(c, &data)) != 0) { error("Unable to parse certificate options: %s", ssh_err(r)); goto out; } debug3("found certificate option \"%.100s\" len %zu", name, sshbuf_len(data)); found = 0; if ((which & OPTIONS_EXTENSIONS) != 0) { if (strcmp(name, "permit-X11-forwarding") == 0) { *cert_no_x11_forwarding_flag = 0; found = 1; } else if (strcmp(name, "permit-agent-forwarding") == 0) { *cert_no_agent_forwarding_flag = 0; found = 1; } else if (strcmp(name, "permit-port-forwarding") == 0) { *cert_no_port_forwarding_flag = 0; found = 1; } else if (strcmp(name, "permit-pty") == 0) { *cert_no_pty_flag = 0; found = 1; } else if (strcmp(name, "permit-user-rc") == 0) { *cert_no_user_rc = 0; found = 1; } } if (!found && (which & OPTIONS_CRITICAL) != 0) { if (strcmp(name, "force-command") == 0) { if ((r = sshbuf_get_cstring(data, &command, NULL)) != 0) { error("Unable to parse \"%s\" " "section: %s", name, ssh_err(r)); goto out; } if (*cert_forced_command != NULL) { error("Certificate has multiple " "force-command options"); free(command); goto out; } *cert_forced_command = command; found = 1; } if (strcmp(name, "source-address") == 0) { if ((r = sshbuf_get_cstring(data, &allowed, NULL)) != 0) { error("Unable to parse \"%s\" " "section: %s", name, ssh_err(r)); goto out; } if ((*cert_source_address_done)++) { error("Certificate has multiple " "source-address options"); free(allowed); goto out; } remote_ip = get_remote_ipaddr(); result = addr_match_cidr_list(remote_ip, allowed); free(allowed); switch (result) { case 1: /* accepted */ break; case 0: /* no match */ logit("Authentication tried for %.100s " "with valid certificate but not " "from a permitted host " "(ip=%.200s).", pw->pw_name, remote_ip); auth_debug_add("Your address '%.200s' " "is not permitted to use this " "certificate for login.", remote_ip); goto out; case -1: default: error("Certificate source-address " "contents invalid"); goto out; } found = 1; } } if (!found) { if (crit) { error("Certificate critical option \"%s\" " "is not supported", name); goto out; } else { logit("Certificate extension \"%s\" " "is not supported", name); } } else if (sshbuf_len(data) != 0) { error("Certificate option \"%s\" corrupt " "(extra data)", name); goto out; } free(name); name = NULL; } /* successfully parsed all options */ ret = 0; out: if (ret != 0 && cert_forced_command != NULL && *cert_forced_command != NULL) { free(*cert_forced_command); *cert_forced_command = NULL; } free(name); sshbuf_free(data); sshbuf_free(c); return ret; } /* * Set options from critical certificate options. These supersede user key * options so this must be called after auth_parse_options(). */ int auth_cert_options(struct sshkey *k, struct passwd *pw) { int cert_no_port_forwarding_flag = 1; int cert_no_agent_forwarding_flag = 1; int cert_no_x11_forwarding_flag = 1; int cert_no_pty_flag = 1; int cert_no_user_rc = 1; char *cert_forced_command = NULL; int cert_source_address_done = 0; /* Separate options and extensions for v01 certs */ if (parse_option_list(k->cert->critical, pw, OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, &cert_forced_command, &cert_source_address_done) == -1) return -1; if (parse_option_list(k->cert->extensions, pw, OPTIONS_EXTENSIONS, 0, &cert_no_port_forwarding_flag, &cert_no_agent_forwarding_flag, &cert_no_x11_forwarding_flag, &cert_no_pty_flag, &cert_no_user_rc, NULL, NULL) == -1) return -1; no_port_forwarding_flag |= cert_no_port_forwarding_flag; no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; no_pty_flag |= cert_no_pty_flag; no_user_rc |= cert_no_user_rc; /* CA-specified forced command supersedes key option */ if (cert_forced_command != NULL) { free(forced_command); forced_command = cert_forced_command; } return 0; } openssh-7.2p2/auth-options.h010064400017500001750000000023711267006270000142600ustar00djmdjm/* $OpenBSD: auth-options.h,v 1.21 2015/01/14 10:30:34 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 int no_user_rc; extern char *forced_command; extern struct envstring *custom_environment; extern int forced_tun_device; extern int key_is_cert_authority; extern char *authorized_principals; int auth_parse_options(struct passwd *, char *, char *, u_long); void auth_clear_options(void); int auth_cert_options(struct sshkey *, struct passwd *); #endif openssh-7.2p2/auth-pam.c010064400017500001750000000754371267006270000133520ustar00djmdjm/*- * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by ThinkSec AS and * NAI Labs, the Security Research Division of Network Associates, Inc. * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the * DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Copyright (c) 2003,2004 Damien Miller * Copyright (c) 2003,2004 Darren Tucker * * 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. */ /* Based on FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des */ #include "includes.h" #include #include #include #include #include #include #include #include #ifdef USE_PAM #if defined(HAVE_SECURITY_PAM_APPL_H) #include #elif defined (HAVE_PAM_PAM_APPL_H) #include #endif /* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */ #ifdef PAM_SUN_CODEBASE # define sshpam_const /* Solaris, HP-UX, AIX */ #else # define sshpam_const const /* LinuxPAM, OpenPAM */ #endif /* Ambiguity in spec: is it an array of pointers or a pointer to an array? */ #ifdef PAM_SUN_CODEBASE # define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) #else # define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) #endif #include "xmalloc.h" #include "buffer.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "auth-pam.h" #include "canohost.h" #include "log.h" #include "msg.h" #include "packet.h" #include "misc.h" #include "servconf.h" #include "ssh2.h" #include "auth-options.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" extern ServerOptions options; extern Buffer loginmsg; extern int compat20; extern u_int utmp_len; /* so we don't silently change behaviour */ #ifdef USE_POSIX_THREADS # error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK" #endif /* * Formerly known as USE_POSIX_THREADS, using this is completely unsupported * and generally a bad idea. Use at own risk and do not expect support if * this breaks. */ #ifdef UNSUPPORTED_POSIX_THREADS_HACK #include /* * Avoid namespace clash when *not* using pthreads for systems *with* * pthreads, which unconditionally define pthread_t via sys/types.h * (e.g. Linux) */ typedef pthread_t sp_pthread_t; #else typedef pid_t sp_pthread_t; #endif struct pam_ctxt { sp_pthread_t pam_thread; int pam_psock; int pam_csock; int pam_done; }; static void sshpam_free_ctx(void *); static struct pam_ctxt *cleanup_ctxt; #ifndef UNSUPPORTED_POSIX_THREADS_HACK /* * Simulate threads with processes. */ static int sshpam_thread_status = -1; static mysig_t sshpam_oldsig; static void sshpam_sigchld_handler(int sig) { signal(SIGCHLD, SIG_DFL); if (cleanup_ctxt == NULL) return; /* handler called after PAM cleanup, shouldn't happen */ if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) <= 0) { /* PAM thread has not exitted, privsep slave must have */ kill(cleanup_ctxt->pam_thread, SIGTERM); if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) <= 0) return; /* could not wait */ } if (WIFSIGNALED(sshpam_thread_status) && WTERMSIG(sshpam_thread_status) == SIGTERM) return; /* terminated by pthread_cancel */ if (!WIFEXITED(sshpam_thread_status)) sigdie("PAM: authentication thread exited unexpectedly"); if (WEXITSTATUS(sshpam_thread_status) != 0) sigdie("PAM: authentication thread exited uncleanly"); } /* ARGSUSED */ static void pthread_exit(void *value) { _exit(0); } /* ARGSUSED */ static int pthread_create(sp_pthread_t *thread, const void *attr, void *(*thread_start)(void *), void *arg) { pid_t pid; struct pam_ctxt *ctx = arg; sshpam_thread_status = -1; switch ((pid = fork())) { case -1: error("fork(): %s", strerror(errno)); return (-1); case 0: close(ctx->pam_psock); ctx->pam_psock = -1; thread_start(arg); _exit(1); default: *thread = pid; close(ctx->pam_csock); ctx->pam_csock = -1; sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); return (0); } } static int pthread_cancel(sp_pthread_t thread) { signal(SIGCHLD, sshpam_oldsig); return (kill(thread, SIGTERM)); } /* ARGSUSED */ static int pthread_join(sp_pthread_t thread, void **value) { int status; if (sshpam_thread_status != -1) return (sshpam_thread_status); signal(SIGCHLD, sshpam_oldsig); waitpid(thread, &status, 0); return (status); } #endif static pam_handle_t *sshpam_handle = NULL; static int sshpam_err = 0; static int sshpam_authenticated = 0; static int sshpam_session_open = 0; static int sshpam_cred_established = 0; static int sshpam_account_status = -1; static char **sshpam_env = NULL; static Authctxt *sshpam_authctxt = NULL; static const char *sshpam_password = NULL; static char badpw[] = "\b\n\r\177INCORRECT"; /* Some PAM implementations don't implement this */ #ifndef HAVE_PAM_GETENVLIST static char ** pam_getenvlist(pam_handle_t *pamh) { /* * XXX - If necessary, we can still support envrionment passing * for platforms without pam_getenvlist by searching for known * env vars (e.g. KRB5CCNAME) from the PAM environment. */ return NULL; } #endif /* * Some platforms, notably Solaris, do not enforce password complexity * rules during pam_chauthtok() if the real uid of the calling process * is 0, on the assumption that it's being called by "passwd" run by root. * This wraps pam_chauthtok and sets/restore the real uid so PAM will do * the right thing. */ #ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID static int sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags) { int result; if (sshpam_authctxt == NULL) fatal("PAM: sshpam_authctxt not initialized"); if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1) fatal("%s: setreuid failed: %s", __func__, strerror(errno)); result = pam_chauthtok(pamh, flags); if (setreuid(0, -1) == -1) fatal("%s: setreuid failed: %s", __func__, strerror(errno)); return result; } # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) #endif void sshpam_password_change_required(int reqd) { debug3("%s %d", __func__, reqd); if (sshpam_authctxt == NULL) fatal("%s: PAM authctxt not initialized", __func__); sshpam_authctxt->force_pwchange = reqd; if (reqd) { no_port_forwarding_flag |= 2; no_agent_forwarding_flag |= 2; no_x11_forwarding_flag |= 2; } else { no_port_forwarding_flag &= ~2; no_agent_forwarding_flag &= ~2; no_x11_forwarding_flag &= ~2; } } /* Import regular and PAM environment from subprocess */ static void import_environments(Buffer *b) { char *env; u_int i, num_env; int err; debug3("PAM: %s entering", __func__); #ifndef UNSUPPORTED_POSIX_THREADS_HACK /* Import variables set by do_pam_account */ sshpam_account_status = buffer_get_int(b); sshpam_password_change_required(buffer_get_int(b)); /* Import environment from subprocess */ num_env = buffer_get_int(b); if (num_env > 1024) fatal("%s: received %u environment variables, expected <= 1024", __func__, num_env); sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); debug3("PAM: num env strings %d", num_env); for(i = 0; i < num_env; i++) sshpam_env[i] = buffer_get_string(b, NULL); sshpam_env[num_env] = NULL; /* Import PAM environment from subprocess */ num_env = buffer_get_int(b); debug("PAM: num PAM env strings %d", num_env); for(i = 0; i < num_env; i++) { env = buffer_get_string(b, NULL); #ifdef HAVE_PAM_PUTENV /* Errors are not fatal here */ if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { error("PAM: pam_putenv: %s", pam_strerror(sshpam_handle, sshpam_err)); } #endif } #endif } /* * Conversation function for authentication thread. */ static int sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { Buffer buffer; struct pam_ctxt *ctxt; struct pam_response *reply; int i; debug3("PAM: %s entering, %d messages", __func__, n); *resp = NULL; if (data == NULL) { error("PAM: conversation function passed a null context"); return (PAM_CONV_ERR); } ctxt = data; if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); if ((reply = calloc(n, sizeof(*reply))) == NULL) return (PAM_CONV_ERR); buffer_init(&buffer); for (i = 0; i < n; ++i) { switch (PAM_MSG_MEMBER(msg, i, msg_style)) { case PAM_PROMPT_ECHO_OFF: buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); if (ssh_msg_send(ctxt->pam_csock, PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) goto fail; if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) goto fail; if (buffer_get_char(&buffer) != PAM_AUTHTOK) goto fail; reply[i].resp = buffer_get_string(&buffer, NULL); break; case PAM_PROMPT_ECHO_ON: buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); if (ssh_msg_send(ctxt->pam_csock, PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) goto fail; if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) goto fail; if (buffer_get_char(&buffer) != PAM_AUTHTOK) goto fail; reply[i].resp = buffer_get_string(&buffer, NULL); break; case PAM_ERROR_MSG: buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); if (ssh_msg_send(ctxt->pam_csock, PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) goto fail; break; case PAM_TEXT_INFO: buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); if (ssh_msg_send(ctxt->pam_csock, PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) goto fail; break; default: goto fail; } buffer_clear(&buffer); } buffer_free(&buffer); *resp = reply; return (PAM_SUCCESS); fail: for(i = 0; i < n; i++) { free(reply[i].resp); } free(reply); buffer_free(&buffer); return (PAM_CONV_ERR); } /* * Authentication thread. */ static void * sshpam_thread(void *ctxtp) { struct pam_ctxt *ctxt = ctxtp; Buffer buffer; struct pam_conv sshpam_conv; int flags = (options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0); #ifndef UNSUPPORTED_POSIX_THREADS_HACK extern char **environ; char **env_from_pam; u_int i; const char *pam_user; const char **ptr_pam_user = &pam_user; char *tz = getenv("TZ"); sshpam_err = pam_get_item(sshpam_handle, PAM_USER, (sshpam_const void **)ptr_pam_user); if (sshpam_err != PAM_SUCCESS) goto auth_fail; environ[0] = NULL; if (tz != NULL) if (setenv("TZ", tz, 1) == -1) error("PAM: could not set TZ environment: %s", strerror(errno)); if (sshpam_authctxt != NULL) { setproctitle("%s [pam]", sshpam_authctxt->valid ? pam_user : "unknown"); } #endif sshpam_conv.conv = sshpam_thread_conv; sshpam_conv.appdata_ptr = ctxt; if (sshpam_authctxt == NULL) fatal("%s: PAM authctxt not initialized", __func__); buffer_init(&buffer); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&sshpam_conv); if (sshpam_err != PAM_SUCCESS) goto auth_fail; sshpam_err = pam_authenticate(sshpam_handle, flags); if (sshpam_err != PAM_SUCCESS) goto auth_fail; if (compat20) { if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; goto auth_fail; } if (sshpam_authctxt->force_pwchange) { sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); if (sshpam_err != PAM_SUCCESS) goto auth_fail; sshpam_password_change_required(0); } } buffer_put_cstring(&buffer, "OK"); #ifndef UNSUPPORTED_POSIX_THREADS_HACK /* Export variables set by do_pam_account */ buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); /* Export any environment strings set in child */ for(i = 0; environ[i] != NULL; i++) ; /* Count */ buffer_put_int(&buffer, i); for(i = 0; environ[i] != NULL; i++) buffer_put_cstring(&buffer, environ[i]); /* Export any environment strings set by PAM in child */ env_from_pam = pam_getenvlist(sshpam_handle); for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) ; /* Count */ buffer_put_int(&buffer, i); for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) buffer_put_cstring(&buffer, env_from_pam[i]); #endif /* UNSUPPORTED_POSIX_THREADS_HACK */ /* XXX - can't do much about an error here */ ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); buffer_free(&buffer); pthread_exit(NULL); auth_fail: buffer_put_cstring(&buffer, pam_strerror(sshpam_handle, sshpam_err)); /* XXX - can't do much about an error here */ if (sshpam_err == PAM_ACCT_EXPIRED) ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); else ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); buffer_free(&buffer); pthread_exit(NULL); return (NULL); /* Avoid warning for non-pthread case */ } void sshpam_thread_cleanup(void) { struct pam_ctxt *ctxt = cleanup_ctxt; debug3("PAM: %s entering", __func__); if (ctxt != NULL && ctxt->pam_thread != 0) { pthread_cancel(ctxt->pam_thread); pthread_join(ctxt->pam_thread, NULL); close(ctxt->pam_psock); close(ctxt->pam_csock); memset(ctxt, 0, sizeof(*ctxt)); cleanup_ctxt = NULL; } } static int sshpam_null_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { debug3("PAM: %s entering, %d messages", __func__, n); return (PAM_CONV_ERR); } static struct pam_conv null_conv = { sshpam_null_conv, NULL }; static int sshpam_store_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; int i; size_t len; debug3("PAM: %s called with %d messages", __func__, n); *resp = NULL; if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); if ((reply = calloc(n, sizeof(*reply))) == NULL) return (PAM_CONV_ERR); for (i = 0; i < n; ++i) { switch (PAM_MSG_MEMBER(msg, i, msg_style)) { case PAM_ERROR_MSG: case PAM_TEXT_INFO: len = strlen(PAM_MSG_MEMBER(msg, i, msg)); buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len); buffer_append(&loginmsg, "\n", 1 ); reply[i].resp_retcode = PAM_SUCCESS; break; default: goto fail; } } *resp = reply; return (PAM_SUCCESS); fail: for(i = 0; i < n; i++) { free(reply[i].resp); } free(reply); return (PAM_CONV_ERR); } static struct pam_conv store_conv = { sshpam_store_conv, NULL }; void sshpam_cleanup(void) { if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor())) return; debug("PAM: cleanup"); pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); if (sshpam_session_open) { debug("PAM: closing session"); pam_close_session(sshpam_handle, PAM_SILENT); sshpam_session_open = 0; } if (sshpam_cred_established) { debug("PAM: deleting credentials"); pam_setcred(sshpam_handle, PAM_DELETE_CRED); sshpam_cred_established = 0; } sshpam_authenticated = 0; pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; } static int sshpam_init(Authctxt *authctxt) { extern char *__progname; const char *pam_rhost, *pam_user, *user = authctxt->user; const char **ptr_pam_user = &pam_user; if (sshpam_handle != NULL) { /* We already have a PAM context; check if the user matches */ sshpam_err = pam_get_item(sshpam_handle, PAM_USER, (sshpam_const void **)ptr_pam_user); if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) return (0); pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; } debug("PAM: initializing for \"%s\"", user); sshpam_err = pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle); sshpam_authctxt = authctxt; if (sshpam_err != PAM_SUCCESS) { pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; return (-1); } pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns); debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); if (sshpam_err != PAM_SUCCESS) { pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; return (-1); } #ifdef PAM_TTY_KLUDGE /* * Some silly PAM modules (e.g. pam_time) require a TTY to operate. * sshd doesn't set the tty until too late in the auth process and * may not even set one (for tty-less connections) */ debug("PAM: setting PAM_TTY to \"ssh\""); sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh"); if (sshpam_err != PAM_SUCCESS) { pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; return (-1); } #endif return (0); } static void * sshpam_init_ctx(Authctxt *authctxt) { struct pam_ctxt *ctxt; int socks[2]; debug3("PAM: %s entering", __func__); /* * Refuse to start if we don't have PAM enabled or do_pam_account * has previously failed. */ if (!options.use_pam || sshpam_account_status == 0) return NULL; /* Initialize PAM */ if (sshpam_init(authctxt) == -1) { error("PAM: initialization failed"); return (NULL); } ctxt = xcalloc(1, sizeof *ctxt); /* Start the authentication thread */ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { error("PAM: failed create sockets: %s", strerror(errno)); free(ctxt); return (NULL); } ctxt->pam_psock = socks[0]; ctxt->pam_csock = socks[1]; if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) { error("PAM: failed to start authentication thread: %s", strerror(errno)); close(socks[0]); close(socks[1]); free(ctxt); return (NULL); } cleanup_ctxt = ctxt; return (ctxt); } static int sshpam_query(void *ctx, char **name, char **info, u_int *num, char ***prompts, u_int **echo_on) { Buffer buffer; struct pam_ctxt *ctxt = ctx; size_t plen; u_char type; char *msg; size_t len, mlen; debug3("PAM: %s entering", __func__); buffer_init(&buffer); *name = xstrdup(""); *info = xstrdup(""); *prompts = xmalloc(sizeof(char *)); **prompts = NULL; plen = 0; *echo_on = xmalloc(sizeof(u_int)); while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { type = buffer_get_char(&buffer); msg = buffer_get_string(&buffer, NULL); mlen = strlen(msg); switch (type) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: *num = 1; len = plen + mlen + 1; **prompts = xreallocarray(**prompts, 1, len); strlcpy(**prompts + plen, msg, len - plen); plen += mlen; **echo_on = (type == PAM_PROMPT_ECHO_ON); free(msg); return (0); case PAM_ERROR_MSG: case PAM_TEXT_INFO: /* accumulate messages */ len = plen + mlen + 2; **prompts = xreallocarray(**prompts, 1, len); strlcpy(**prompts + plen, msg, len - plen); plen += mlen; strlcat(**prompts + plen, "\n", len - plen); plen++; free(msg); break; case PAM_ACCT_EXPIRED: sshpam_account_status = 0; /* FALLTHROUGH */ case PAM_AUTH_ERR: debug3("PAM: %s", pam_strerror(sshpam_handle, type)); if (**prompts != NULL && strlen(**prompts) != 0) { *info = **prompts; **prompts = NULL; *num = 0; **echo_on = 0; ctxt->pam_done = -1; free(msg); return 0; } /* FALLTHROUGH */ case PAM_SUCCESS: if (**prompts != NULL) { /* drain any accumulated messages */ debug("PAM: %s", **prompts); buffer_append(&loginmsg, **prompts, strlen(**prompts)); free(**prompts); **prompts = NULL; } if (type == PAM_SUCCESS) { if (!sshpam_authctxt->valid || (sshpam_authctxt->pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)) fatal("Internal error: PAM auth " "succeeded when it should have " "failed"); import_environments(&buffer); *num = 0; **echo_on = 0; ctxt->pam_done = 1; free(msg); return (0); } error("PAM: %s for %s%.100s from %.100s", msg, sshpam_authctxt->valid ? "" : "illegal user ", sshpam_authctxt->user, get_remote_name_or_ip(utmp_len, options.use_dns)); /* FALLTHROUGH */ default: *num = 0; **echo_on = 0; free(msg); ctxt->pam_done = -1; return (-1); } } return (-1); } /* XXX - see also comment in auth-chall.c:verify_response */ static int sshpam_respond(void *ctx, u_int num, char **resp) { Buffer buffer; struct pam_ctxt *ctxt = ctx; debug2("PAM: %s entering, %u responses", __func__, num); switch (ctxt->pam_done) { case 1: sshpam_authenticated = 1; return (0); case 0: break; default: return (-1); } if (num != 1) { error("PAM: expected one response, got %u", num); return (-1); } buffer_init(&buffer); if (sshpam_authctxt->valid && (sshpam_authctxt->pw->pw_uid != 0 || options.permit_root_login == PERMIT_YES)) buffer_put_cstring(&buffer, *resp); else buffer_put_cstring(&buffer, badpw); if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { buffer_free(&buffer); return (-1); } buffer_free(&buffer); return (1); } static void sshpam_free_ctx(void *ctxtp) { struct pam_ctxt *ctxt = ctxtp; debug3("PAM: %s entering", __func__); sshpam_thread_cleanup(); free(ctxt); /* * We don't call sshpam_cleanup() here because we may need the PAM * handle at a later stage, e.g. when setting up a session. It's * still on the cleanup list, so pam_end() *will* be called before * the server process terminates. */ } KbdintDevice sshpam_device = { "pam", sshpam_init_ctx, sshpam_query, sshpam_respond, sshpam_free_ctx }; KbdintDevice mm_sshpam_device = { "pam", mm_sshpam_init_ctx, mm_sshpam_query, mm_sshpam_respond, mm_sshpam_free_ctx }; /* * This replaces auth-pam.c */ void start_pam(Authctxt *authctxt) { if (!options.use_pam) fatal("PAM: initialisation requested when UsePAM=no"); if (sshpam_init(authctxt) == -1) fatal("PAM: initialisation failed"); } void finish_pam(void) { sshpam_cleanup(); } u_int do_pam_account(void) { debug("%s: called", __func__); if (sshpam_account_status != -1) return (sshpam_account_status); sshpam_err = pam_acct_mgmt(sshpam_handle, 0); debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, pam_strerror(sshpam_handle, sshpam_err)); if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { sshpam_account_status = 0; return (sshpam_account_status); } if (sshpam_err == PAM_NEW_AUTHTOK_REQD) sshpam_password_change_required(1); sshpam_account_status = 1; return (sshpam_account_status); } void do_pam_set_tty(const char *tty) { if (tty != NULL) { debug("PAM: setting PAM_TTY to \"%s\"", tty); sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty); if (sshpam_err != PAM_SUCCESS) fatal("PAM: failed to set PAM_TTY: %s", pam_strerror(sshpam_handle, sshpam_err)); } } void do_pam_setcred(int init) { sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&store_conv); if (sshpam_err != PAM_SUCCESS) fatal("PAM: failed to set PAM_CONV: %s", pam_strerror(sshpam_handle, sshpam_err)); if (init) { debug("PAM: establishing credentials"); sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED); } else { debug("PAM: reinitializing credentials"); sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED); } if (sshpam_err == PAM_SUCCESS) { sshpam_cred_established = 1; return; } if (sshpam_authenticated) fatal("PAM: pam_setcred(): %s", pam_strerror(sshpam_handle, sshpam_err)); else debug("PAM: pam_setcred(): %s", pam_strerror(sshpam_handle, sshpam_err)); } static int sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { char input[PAM_MAX_MSG_SIZE]; struct pam_response *reply; int i; debug3("PAM: %s called with %d messages", __func__, n); *resp = NULL; if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) return (PAM_CONV_ERR); if ((reply = calloc(n, sizeof(*reply))) == NULL) return (PAM_CONV_ERR); for (i = 0; i < n; ++i) { switch (PAM_MSG_MEMBER(msg, i, msg_style)) { case PAM_PROMPT_ECHO_OFF: reply[i].resp = read_passphrase(PAM_MSG_MEMBER(msg, i, msg), RP_ALLOW_STDIN); reply[i].resp_retcode = PAM_SUCCESS; break; case PAM_PROMPT_ECHO_ON: fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); if (fgets(input, sizeof input, stdin) == NULL) input[0] = '\0'; if ((reply[i].resp = strdup(input)) == NULL) goto fail; reply[i].resp_retcode = PAM_SUCCESS; break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); reply[i].resp_retcode = PAM_SUCCESS; break; default: goto fail; } } *resp = reply; return (PAM_SUCCESS); fail: for(i = 0; i < n; i++) { free(reply[i].resp); } free(reply); return (PAM_CONV_ERR); } static struct pam_conv tty_conv = { sshpam_tty_conv, NULL }; /* * XXX this should be done in the authentication phase, but ssh1 doesn't * support that */ void do_pam_chauthtok(void) { if (use_privsep) fatal("Password expired (unable to change with privsep)"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&tty_conv); if (sshpam_err != PAM_SUCCESS) fatal("PAM: failed to set PAM_CONV: %s", pam_strerror(sshpam_handle, sshpam_err)); debug("PAM: changing password"); sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); if (sshpam_err != PAM_SUCCESS) fatal("PAM: pam_chauthtok(): %s", pam_strerror(sshpam_handle, sshpam_err)); } void do_pam_session(void) { debug3("PAM: opening session"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&store_conv); if (sshpam_err != PAM_SUCCESS) fatal("PAM: failed to set PAM_CONV: %s", pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_open_session(sshpam_handle, 0); if (sshpam_err == PAM_SUCCESS) sshpam_session_open = 1; else { sshpam_session_open = 0; disable_forwarding(); error("PAM: pam_open_session(): %s", pam_strerror(sshpam_handle, sshpam_err)); } } int is_pam_session_open(void) { return sshpam_session_open; } /* * Set a PAM environment string. We need to do this so that the session * modules can handle things like Kerberos/GSI credentials that appear * during the ssh authentication process. */ int do_pam_putenv(char *name, char *value) { int ret = 1; #ifdef HAVE_PAM_PUTENV char *compound; size_t len; len = strlen(name) + strlen(value) + 2; compound = xmalloc(len); snprintf(compound, len, "%s=%s", name, value); ret = pam_putenv(sshpam_handle, compound); free(compound); #endif return (ret); } char ** fetch_pam_child_environment(void) { return sshpam_env; } char ** fetch_pam_environment(void) { return (pam_getenvlist(sshpam_handle)); } void free_pam_environment(char **env) { char **envp; if (env == NULL) return; for (envp = env; *envp; envp++) free(*envp); free(env); } /* * "Blind" conversation function for password authentication. Assumes that * echo-off prompts are for the password and stores messages for later * display. */ static int sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; int i; size_t len; debug3("PAM: %s called with %d messages", __func__, n); *resp = NULL; if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); if ((reply = calloc(n, sizeof(*reply))) == NULL) return (PAM_CONV_ERR); for (i = 0; i < n; ++i) { switch (PAM_MSG_MEMBER(msg, i, msg_style)) { case PAM_PROMPT_ECHO_OFF: if (sshpam_password == NULL) goto fail; if ((reply[i].resp = strdup(sshpam_password)) == NULL) goto fail; reply[i].resp_retcode = PAM_SUCCESS; break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: len = strlen(PAM_MSG_MEMBER(msg, i, msg)); if (len > 0) { buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len); buffer_append(&loginmsg, "\n", 1); } if ((reply[i].resp = strdup("")) == NULL) goto fail; reply[i].resp_retcode = PAM_SUCCESS; break; default: goto fail; } } *resp = reply; return (PAM_SUCCESS); fail: for(i = 0; i < n; i++) { free(reply[i].resp); } free(reply); return (PAM_CONV_ERR); } static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL }; /* * Attempt password authentication via PAM */ int sshpam_auth_passwd(Authctxt *authctxt, const char *password) { int flags = (options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0); if (!options.use_pam || sshpam_handle == NULL) fatal("PAM: %s called when PAM disabled or failed to " "initialise.", __func__); sshpam_password = password; sshpam_authctxt = authctxt; /* * If the user logging in is invalid, or is root but is not permitted * by PermitRootLogin, use an invalid password to prevent leaking * information via timing (eg if the PAM config has a delay on fail). */ if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)) sshpam_password = badpw; sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&passwd_conv); if (sshpam_err != PAM_SUCCESS) fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, pam_strerror(sshpam_handle, sshpam_err)); sshpam_err = pam_authenticate(sshpam_handle, flags); sshpam_password = NULL; if (sshpam_err == PAM_SUCCESS && authctxt->valid) { debug("PAM: password authentication accepted for %.100s", authctxt->user); return 1; } else { debug("PAM: password authentication failed for %.100s: %s", authctxt->valid ? authctxt->user : "an illegal user", pam_strerror(sshpam_handle, sshpam_err)); return 0; } } #endif /* USE_PAM */ openssh-7.2p2/auth-pam.h010064400017500001750000000037301267006270000133420ustar00djmdjm/* $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 */ openssh-7.2p2/auth-passwd.c010064400017500001750000000143111267006270000140560ustar00djmdjm/* $OpenBSD: auth-passwd.c,v 1.44 2014/07/15 15:54:14 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include #include "packet.h" #include "buffer.h" #include "log.h" #include "misc.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 { 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 encrypted_password != NULL && strcmp(encrypted_password, pw_password) == 0; } #endif openssh-7.2p2/auth-rh-rsa.c010064400017500001750000000060371267006270000137570ustar00djmdjm/* $OpenBSD: auth-rh-rsa.c,v 1.44 2014/07/15 15:54:14 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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" #ifdef WITH_SSH1 #include #include #include #include "packet.h" #include "uidswap.h" #include "log.h" #include "buffer.h" #include "misc.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; if (auth_key_is_revoked(client_host_key)) return 0; /* 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; } #endif /* WITH_SSH1 */ openssh-7.2p2/auth-rhosts.c010064400017500001750000000224471267006270000141100ustar00djmdjm/* $OpenBSD: auth-rhosts.c,v 1.46 2014/12/23 22:42:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #ifdef HAVE_NETGROUP_H # include #endif #include #include #include #include #include #include #include "packet.h" #include "buffer.h" #include "uidswap.h" #include "pathnames.h" #include "log.h" #include "misc.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; #define RBUFLN 1024 char buf[RBUFLN];/* Must not be larger than host, user, dummy below. */ int fd; struct stat st; /* Open the .rhosts file, deny if unreadable */ if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1) return 0; if (fstat(fd, &st) == -1) { close(fd); return 0; } if (!S_ISREG(st.st_mode)) { logit("User %s hosts file %s is not a regular file", server_user, filename); close(fd); return 0; } unset_nonblock(fd); if ((f = fdopen(fd, "r")) == NULL) { close(fd); return 0; } while (fgets(buf, sizeof(buf), f)) { /* All three must have length >= buf to avoid overflows. */ char hostbuf[RBUFLN], userbuf[RBUFLN], dummy[RBUFLN]; char *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 and * no system hosts.equiv/shosts.equiv files exist then 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) { debug3("%s: no hosts access files exist", __func__); return 0; } /* * If not logging in as superuser, try /etc/hosts.equiv and * shosts.equiv. */ if (pw->pw_uid == 0) debug3("%s: root user, ignoring system hosts files", __func__); else { 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) { return auth_rhosts2_raw(pw, client_user, hostname, ipaddr); } openssh-7.2p2/auth-rsa.c010064400017500001750000000220661267006270000133500ustar00djmdjm/* $OpenBSD: auth-rsa.c,v 1.90 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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" #ifdef WITH_SSH1 #include #include #include #include #include #include #include #include "xmalloc.h" #include "rsa.h" #include "packet.h" #include "ssh1.h" #include "uidswap.h" #include "match.h" #include "buffer.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "servconf.h" #include "key.h" #include "auth-options.h" #include "hostfile.h" #include "auth.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "ssh.h" #include "digest.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]; struct ssh_digest_ctx *md; int len; /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { error("%s: RSA modulus too small: %d < minimum %d bits", __func__, 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("%s: bad challenge length %d", __func__, len); memset(buf, 0, 32); BN_bn2bin(challenge, buf + 32 - len); if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || ssh_digest_update(md, buf, 32) < 0 || ssh_digest_update(md, session_id, 16) < 0 || ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0) fatal("%s: md5 failed", __func__); ssh_digest_free(md); /* Verify that the response is the original challenge. */ if (timingsafe_bcmp(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. */ if (rsa_public_encrypt(encrypted_challenge, challenge, key->rsa) != 0) fatal("%s: rsa_public_encrypt failed", __func__); /* 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); } static int rsa_key_allowed_in_file(struct passwd *pw, char *file, const BIGNUM *client_n, Key **rkey) { char *fp, line[SSH_MAX_PUBKEY_BYTES]; int allowed = 0, bits; FILE *f; u_long linenum = 0; Key *key; debug("trying public RSA key file %s", file); if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL) return 0; /* * 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. */ key = key_new(KEY_RSA1); 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 != keybits) logit("Warning: %s, line %lu: keysize mismatch: " "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(key), fp); free(fp); /* Never accept a revoked key */ if (auth_key_is_revoked(key)) break; /* 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; if (key_is_cert_authority) continue; /* break out, this key is allowed */ allowed = 1; break; } /* Close the file. */ fclose(f); /* return key if allowed */ if (allowed && rkey != NULL) *rkey = key; else key_free(key); return allowed; } /* * 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 *file; u_int i, allowed = 0; temporarily_use_uid(pw); for (i = 0; !allowed && i < options.num_authkeys_files; i++) { if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey); free(file); } restore_uid(); 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; 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. */ pubkey_auth_info(authctxt, key, NULL); packet_send_debug("RSA authentication accepted."); return (1); } #endif /* WITH_SSH1 */ openssh-7.2p2/auth-shadow.c010064400017500001750000000103421267006270000140420ustar00djmdjm/* * 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 #include #include #include #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 */ openssh-7.2p2/auth-sia.c010064400017500001750000000061641267006270000133400ustar00djmdjm/* * 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 #include #include #include #include #include #include #include #include #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 */ openssh-7.2p2/auth-sia.h010064400017500001750000000026331267006270000133420ustar00djmdjm/* * 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 */ openssh-7.2p2/auth-skey.c010064400017500001750000000054251267006270000135360ustar00djmdjm/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk 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 #include #include #include #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "ssh-gss.h" #include "log.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 */ openssh-7.2p2/auth.c010064400017500001750000000467321267006270000125730ustar00djmdjm/* $OpenBSD: auth.c,v 1.113 2015/08/21 03:42:19 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 "includes.h" #include #include #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #ifdef HAVE_LOGIN_H #include #endif #ifdef USE_SHADOW #include #endif #ifdef HAVE_LIBGEN_H #include #endif #include #include #include #include #include #include "xmalloc.h" #include "match.h" #include "groupaccess.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "auth-options.h" #include "canohost.h" #include "uidswap.h" #include "packet.h" #include "loginrec.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "authfile.h" #include "monitor_wrap.h" #include "authfile.h" #include "ssherr.h" #include "compat.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; 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 */ passwd = pw->pw_passwd; #ifdef USE_SHADOW if (spw != NULL) #ifdef USE_LIBIAF passwd = get_iaf_password(pw); #else passwd = spw->sp_pwdp; #endif /* USE_LIBIAF */ #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 #ifdef USE_LIBIAF free((void *) passwd); #endif /* USE_LIBIAF */ if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Deny if shell does not exist or is not executable unless we * are chrooting. */ if (options.chroot_directory == NULL || strcasecmp(options.chroot_directory, "none") == 0) { char *shell = xstrdup((pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s " "does not exist", pw->pw_name, shell); free(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); free(shell); return 0; } free(shell); } 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_info(Authctxt *authctxt, const char *fmt, ...) { va_list ap; int i; free(authctxt->info); authctxt->info = NULL; va_start(ap, fmt); i = vasprintf(&authctxt->info, fmt, ap); va_end(ap); if (i < 0 || authctxt->info == NULL) fatal("vasprintf failed"); } void auth_log(Authctxt *authctxt, int authenticated, int partial, const char *method, const char *submethod) { 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 if (partial) authmsg = "Partial"; else authmsg = authenticated ? "Accepted" : "Failed"; authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s", authmsg, method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", authctxt->user, get_remote_ipaddr(), get_remote_port(), compat20 ? "ssh2" : "ssh1", authctxt->info != NULL ? ": " : "", authctxt->info != NULL ? authctxt->info : ""); free(authctxt->info); authctxt->info = NULL; #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 } void auth_maxtries_exceeded(Authctxt *authctxt) { error("maximum authentication attempts exceeded for " "%s%.100s from %.200s port %d %s", authctxt->valid ? "" : "invalid user ", authctxt->user, get_remote_ipaddr(), get_remote_port(), compat20 ? "ssh2" : "ssh1"); packet_disconnect("Too many authentication failures"); /* NOTREACHED */ } /* * Check whether root logins are disallowed. */ int auth_root_allowed(const char *method) { switch (options.permit_root_login) { case PERMIT_YES: return 1; case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || strcmp(method, "gssapi-with-mic") == 0) return 1; break; case PERMIT_FORCED_ONLY: if (forced_command) { logit("Root login accepted for forced command."); return 1; } break; } logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); return 0; } /* * Given a template and a passwd structure, build a filename * by substituting % tokenised options. Currently, %% becomes '%', * %h becomes the home directory and %u the username. * * This returns a buffer allocated by xmalloc. */ char * expand_authorized_keys(const char *filename, struct passwd *pw) { char *file, ret[PATH_MAX]; 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"); free(file); return (xstrdup(ret)); } char * authorized_principals_file(struct passwd *pw) { if (options.authorized_principals_file == NULL) return NULL; return expand_authorized_keys(options.authorized_principals_file, 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) { char *user_hostfile; struct stat st; HostStatus host_status; struct hostkeys *hostkeys; const struct hostkey_entry *found; hostkeys = init_hostkeys(); load_hostkeys(hostkeys, host, sysfile); if (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); auth_debug_add("Ignored %.200s: bad ownership or modes", user_hostfile); } else { temporarily_use_uid(pw); load_hostkeys(hostkeys, host, user_hostfile); restore_uid(); } free(user_hostfile); } host_status = check_key_in_hostkeys(hostkeys, key, &found); if (host_status == HOST_REVOKED) error("WARNING: revoked key for %s attempted authentication", found->host); else if (host_status == HOST_OK) debug("%s: key for %s found at %s:%ld", __func__, found->host, found->file, found->line); else debug("%s: key for host %s not found", __func__, host); free_hostkeys(hostkeys); return host_status; } /* * Check a given path 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 a file name, its stat information (preferably from fstat() to * avoid races), the uid of the expected owner, their home directory and an * error buffer plus max size as arguments. * * Returns 0 on success and -1 on failure */ int auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, uid_t uid, char *err, size_t errlen) { char buf[PATH_MAX], homedir[PATH_MAX]; char *cp; int comparehome = 0; struct stat st; if (realpath(name, buf) == NULL) { snprintf(err, errlen, "realpath %s failed: %s", name, strerror(errno)); return -1; } if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) comparehome = 1; if (!S_ISREG(stp->st_mode)) { snprintf(err, errlen, "%s is not a regular file", buf); return -1; } if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || (stp->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)); if (stat(buf, &st) < 0 || (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || (st.st_mode & 022) != 0) { snprintf(err, errlen, "bad ownership or modes for directory %s", buf); return -1; } /* If are past the homedir then we can stop */ if (comparehome && strcmp(homedir, buf) == 0) 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; } /* * Version of secure_path() that accepts an open file descriptor to * avoid races. * * Returns 0 on success and -1 on failure */ static int secure_filename(FILE *f, const char *file, struct passwd *pw, char *err, size_t errlen) { struct stat st; /* check the open file to avoid races */ if (fstat(fileno(f), &st) < 0) { snprintf(err, errlen, "cannot stat file %s: %s", file, strerror(errno)); return -1; } return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); } static FILE * auth_openfile(const char *file, struct passwd *pw, int strict_modes, int log_missing, char *file_type) { char line[1024]; struct stat st; int fd; FILE *f; if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { if (log_missing || errno != ENOENT) debug("Could not open %s '%s': %s", file_type, file, strerror(errno)); return NULL; } if (fstat(fd, &st) < 0) { close(fd); return NULL; } if (!S_ISREG(st.st_mode)) { logit("User %s %s %s is not a regular file", pw->pw_name, file_type, file); close(fd); return NULL; } unset_nonblock(fd); if ((f = fdopen(fd, "r")) == NULL) { close(fd); return NULL; } if (strict_modes && secure_filename(f, file, pw, line, sizeof(line)) != 0) { fclose(f); logit("Authentication refused: %s", line); auth_debug_add("Ignored %s: %s", file_type, line); return NULL; } return f; } FILE * auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) { return auth_openfile(file, pw, strict_modes, 1, "authorized keys"); } FILE * auth_openprincipals(const char *file, struct passwd *pw, int strict_modes) { return auth_openfile(file, pw, strict_modes, 0, "authorized principals"); } 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; struct connection_info *ci = get_connection_info(1, options.use_dns); ci->user = user; parse_server_match_config(&options, ci); #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_setauthdb(user); #endif pw = getpwnam(user); #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); #endif #ifdef HAVE_CYGWIN /* * Windows usernames are case-insensitive. To avoid later problems * when trying to match the username, the user is only allowed to * login if the username is given in the same case as stored in the * user database. */ if (pw != NULL && strcmp(user, pw->pw_name) != 0) { logit("Login name %.100s does not match stored username %.100s", user, pw->pw_name); pw = NULL; } #endif 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); } /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ int auth_key_is_revoked(Key *key) { char *fp = NULL; int r; if (options.revoked_keys_file == NULL) return 0; if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { r = SSH_ERR_ALLOC_FAIL; error("%s: fingerprint key: %s", __func__, ssh_err(r)); goto out; } r = sshkey_check_revoked(key, options.revoked_keys_file); switch (r) { case 0: break; /* not revoked */ case SSH_ERR_KEY_REVOKED: error("Authentication key %s %s revoked by file %s", sshkey_type(key), fp, options.revoked_keys_file); goto out; default: error("Error checking authentication key %s %s in " "revoked keys file %s: %s", sshkey_type(key), fp, options.revoked_keys_file, ssh_err(r)); goto out; } /* Success */ r = 0; out: free(fp); return r == 0 ? 0 : 1; } 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); free(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"; #ifdef HAVE_STRUCT_PASSWD_PW_GECOS fake.pw_gecos = "NOUSER"; #endif fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; #ifdef HAVE_STRUCT_PASSWD_PW_CLASS fake.pw_class = ""; #endif fake.pw_dir = "/nonexist"; fake.pw_shell = "/nonexist"; return (&fake); } openssh-7.2p2/auth.h010064400017500001750000000166361267006270000126000ustar00djmdjm/* $OpenBSD: auth.h,v 1.86 2015/12/04 16:41:28 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 #include #ifdef HAVE_LOGIN_CAP #include #endif #ifdef BSD_AUTH #include #endif #ifdef KRB5 #include #endif struct ssh; struct sshkey; 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 server_caused_failure; int force_pwchange; char *user; /* username sent by the client */ char *service; struct passwd *pw; /* set if 'valid' */ char *style; void *kbdintctxt; char *info; /* Extra info for next auth_log */ #ifdef BSD_AUTH auth_session_t *as; #endif char **auth_methods; /* modified from server config */ u_int num_auth_methods; #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; struct sshkey **prev_userkeys; u_int nprev_userkeys; }; /* * 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 *, int); void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) __attribute__((__format__ (printf, 3, 4))); void auth2_record_userkey(Authctxt *, struct sshkey *); int auth2_userkey_already_used(Authctxt *, struct sshkey *); struct stat; int auth_secure_path(const char *, struct stat *, const char *, uid_t, char *, size_t); #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 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_info(Authctxt *authctxt, const char *, ...) __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2))); void auth_log(Authctxt *, int, int, const char *, const char *); void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); void userauth_finish(Authctxt *, int, const char *, const char *); int auth_root_allowed(const char *); void userauth_send_banner(const char *); char *auth2_read_banner(void); int auth2_methods_valid(const char *, int); int auth2_update_methods_lists(Authctxt *, const char *, const char *); int auth2_setup_methods_lists(Authctxt *); int auth2_method_allowed(Authctxt *, const char *, const char *); void privsep_challenge_enable(void); int auth2_challenge(Authctxt *, char *); void auth2_challenge_stop(Authctxt *); int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int bsdauth_respond(void *, u_int, char **); int skey_query(void *, char **, char **, u_int *, char ***, u_int **); int skey_respond(void *, u_int, char **); int allowed_user(struct passwd *); struct passwd * getpwnamallow(const char *user); char *get_challenge(Authctxt *); int verify_response(Authctxt *, const char *); void abandon_challenge_response(Authctxt *); char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); int auth_key_is_revoked(Key *); 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_public_by_index(int, struct ssh *); Key *get_hostkey_public_by_type(int, int, struct ssh *); Key *get_hostkey_private_by_type(int, int, struct ssh *); int get_hostkey_index(Key *, int, struct ssh *); int ssh1_session_key(BIGNUM *); int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); /* 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 SKEY_PROMPT "\nS/Key Password: " #if defined(KRB5) && !defined(HEIMDAL) #include krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); #endif #endif openssh-7.2p2/auth1.c010064400017500001750000000242031267006270000126410ustar00djmdjm/* $OpenBSD: auth1.c,v 1.82 2014/07/15 15:54:14 millert Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , 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" #ifdef WITH_SSH1 #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "rsa.h" #include "ssh1.h" #include "packet.h" #include "buffer.h" #include "log.h" #include "misc.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 *); static int auth1_process_rsa(Authctxt *); static int auth1_process_rhosts_rsa(Authctxt *); static int auth1_process_tis_challenge(Authctxt *); static int auth1_process_tis_response(Authctxt *); static char *client_user = NULL; /* Used to fill in remote user for PAM */ struct AuthMethod1 { int type; char *name; int *enabled; int (*method)(Authctxt *); }; 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) { 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)); explicit_bzero(password, dlen); free(password); return (authenticated); } /*ARGSUSED*/ static int auth1_process_rsa(Authctxt *authctxt) { 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) { 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_cstring(&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); auth_info(authctxt, "ruser %.100s", client_user); return (authenticated); } /*ARGSUSED*/ static int auth1_process_tis_challenge(Authctxt *authctxt) { 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); free(challenge); packet_send(); packet_write_wait(); return (-1); } /*ARGSUSED*/ static int auth1_process_tis_response(Authctxt *authctxt) { int authenticated = 0; char *response; u_int dlen; response = packet_get_string(&dlen); packet_check_eom(); authenticated = verify_response(authctxt, response); explicit_bzero(response, dlen); free(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; 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.permit_empty_passwd && 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, 0, "without authentication", NULL); return; } } /* Indicate that authentication is needed. */ packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); for (;;) { /* default to fail */ authenticated = 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 (authctxt->failures >= options.max_authtries) goto skip; 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); 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 */ #ifndef HAVE_CYGWIN /* 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("%s", msg); } #endif skip: /* Log before sending the reply */ auth_log(authctxt, authenticated, 0, get_authname(type), NULL); free(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 auth_maxtries_exceeded(authctxt); } 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_cstring(&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(); } /* Configuration may have changed as a result of Match */ if (options.num_auth_methods != 0) fatal("AuthenticationMethods is not supported with SSH " "protocol 1"); 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(); } #endif /* WITH_SSH1 */ openssh-7.2p2/auth2-chall.c010064400017500001750000000223101267006270000137200ustar00djmdjm/* $OpenBSD: auth2-chall.c,v 1.43 2015/07/18 07:57:14 djm 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 #include #include #include #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 "misc.h" #include "servconf.h" /* import */ extern ServerOptions options; static int auth2_challenge_start(Authctxt *); static int send_userauth_info_request(Authctxt *); static int 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; u_int devices_done; }; #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 = xcalloc(1, 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); free(kbdintctxt->devices); explicit_bzero(kbdintctxt, sizeof(*kbdintctxt)); free(kbdintctxt); } /* get next device */ static int kbdint_next_device(Authctxt *authctxt, 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 ((kbdintctxt->devices_done & (1 << i)) != 0 || !auth2_method_allowed(authctxt, "keyboard-interactive", devices[i]->name)) continue; if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) { kbdintctxt->device = devices[i]; kbdintctxt->devices_done |= 1 << i; } } t = kbdintctxt->devices; kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; free(t); debug2("kbdint_next_device: devices %s", kbdintctxt->devices ? kbdintctxt->devices : ""); } 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 : "", devs ? 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 : ""); if (kbdint_next_device(authctxt, 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++) free(prompts[i]); free(prompts); free(echo_on); free(name); free(instr); return 1; } static int input_userauth_info_response(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; KbdintAuthctxt *kbdintctxt; int authenticated = 0, res; u_int i, nresp; const char *devicename = NULL; char **response = NULL; 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++) { explicit_bzero(response[i], strlen(response[i])); free(response[i]); } free(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; } devicename = 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, "keyboard-interactive", devicename); return 0; } 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 } openssh-7.2p2/auth2-gss.c010064400017500001750000000200521267006270000134320ustar00djmdjm/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #ifdef GSSAPI #include #include #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 "misc.h" #include "servconf.h" #include "packet.h" #include "ssh-gss.h" #include "monitor_wrap.h" extern ServerOptions options; static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); static int 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; 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); } do { mechs--; free(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; ssh_gssapi_test_oid_supported(&ms, &goid, &present); } else { logit("Badly formed OID received"); } } while (mechs > 0 && !present); if (!present) { free(doid); authctxt->server_caused_failure = 1; return (0); } if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { if (ctxt != NULL) ssh_gssapi_delete_ctx(&ctxt); free(doid); authctxt->server_caused_failure = 1; 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(); free(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 int 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)); free(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", NULL); } 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); return 0; } static int 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)); free(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); return 0; } /* * 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 int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; int authenticated; if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) fatal("No authentication or GSSAPI context"); /* * 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", NULL); return 0; } static int 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); free(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", NULL); return 0; } Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, &options.gss_authentication }; #endif /* GSSAPI */ openssh-7.2p2/auth2-hostbased.c010064400017500001750000000163351267006270000146230ustar00djmdjm/* $OpenBSD: auth2-hostbased.c,v 1.25 2015/05/04 06:10:48 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 "includes.h" #include #include #include #include #include "xmalloc.h" #include "ssh2.h" #include "packet.h" #include "buffer.h" #include "log.h" #include "misc.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" #include "match.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; } if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { error("Refusing RSA key because peer uses unsafe " "signature format"); goto done; } if (match_pattern_list(sshkey_ssh_name(key), options.hostbased_key_types, 0) != 1) { logit("%s: key type %s not in HostbasedAcceptedKeyTypes", __func__, sshkey_type(key)); 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 pubkey_auth_info(authctxt, key, "client user \"%.100s\", client host \"%.100s\"", cuser, chost); /* 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); free(pkalg); free(pkblob); free(cuser); free(chost); free(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, *reason; HostStatus host_status; int len; char *fp; if (auth_key_is_revoked(key)) return 0; resolvedname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); debug2("%s: chost %s resolvedname %s ipaddr %s", __func__, chost, resolvedname, ipaddr); if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { debug2("stripping trailing dot from chost %s", chost); chost[len - 1] = '\0'; } if (options.hostbased_uses_name_from_packet_only) { if (auth_rhosts2(pw, cuser, chost, chost) == 0) { debug2("%s: auth_rhosts2 refused " "user \"%.100s\" host \"%.100s\" (from packet)", __func__, cuser, chost); return 0; } lookup = chost; } else { 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) { debug2("%s: auth_rhosts2 refused " "user \"%.100s\" host \"%.100s\" addr \"%.100s\"", __func__, cuser, resolvedname, ipaddr); return 0; } lookup = resolvedname; } debug2("%s: access allowed by auth_rhosts2", __func__); if (key_is_cert(key) && key_cert_check_authority(key, 1, 0, lookup, &reason)) { error("%s", reason); auth_debug_add("%s", reason); return 0; } 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); } if (host_status == HOST_OK) { if (key_is_cert(key)) { if ((fp = sshkey_fingerprint(key->cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted certificate ID \"%s\" signed by " "%s CA %s from %s@%s", key->cert->key_id, key_type(key->cert->signature_key), fp, cuser, lookup); } else { if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted %s public key %s from %s@%s", key_type(key), fp, cuser, lookup); } free(fp); } return (host_status == HOST_OK); } Authmethod method_hostbased = { "hostbased", userauth_hostbased, &options.hostbased_authentication }; openssh-7.2p2/auth2-kbdint.c010064400017500001750000000041751267006270000141210ustar00djmdjm/* $OpenBSD: auth2-kbdint.c,v 1.7 2014/07/15 15:54:14 millert 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 #include #include "xmalloc.h" #include "packet.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "log.h" #include "buffer.h" #include "misc.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); free(devs); free(lang); return authenticated; } Authmethod method_kbdint = { "keyboard-interactive", userauth_kbdint, &options.kbd_interactive_authentication }; openssh-7.2p2/auth2-none.c010064400017500001750000000043531267006270000136030ustar00djmdjm/* $OpenBSD: auth2-none.c,v 1.18 2014/07/15 15:54:14 millert 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 #include #include #include #include #include #include #include #include "atomicio.h" #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "packet.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.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; static int userauth_none(Authctxt *authctxt) { none_enabled = 0; packet_check_eom(); if (options.permit_empty_passwd && options.password_authentication) return (PRIVSEP(auth_password(authctxt, ""))); return (0); } Authmethod method_none = { "none", userauth_none, &none_enabled }; openssh-7.2p2/auth2-passwd.c010064400017500001750000000046151267006270000141460ustar00djmdjm/* $OpenBSD: auth2-passwd.c,v 1.12 2014/07/15 15:54:14 millert 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 #include #include #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 "misc.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); explicit_bzero(newpass, newlen); free(newpass); } packet_check_eom(); if (change) logit("password change not supported"); else if (PRIVSEP(auth_password(authctxt, password)) == 1) authenticated = 1; explicit_bzero(password, len); free(password); return authenticated; } Authmethod method_passwd = { "password", userauth_passwd, &options.password_authentication }; openssh-7.2p2/auth2-pubkey.c010064400017500001750000000714101267006270000141410ustar00djmdjm/* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 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 "includes.h" #include #include #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" #include "packet.h" #include "buffer.h" #include "log.h" #include "misc.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 "authfile.h" #include "match.h" #include "ssherr.h" #include "channels.h" /* XXX for session.h */ #include "session.h" /* XXX for child_set_env(); refactor? */ /* 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, *userstyle, *fp = NULL; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { debug2("%s: disabled because of invalid user", __func__); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("%s: SSH_BUG_PKAUTH", __func__); /* 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("%s: unsupported public key algorithm: %s", __func__, pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("%s: cannot decode key: %s", __func__, pkalg); goto done; } if (key->type != pktype) { error("%s: type mismatch for decoded key " "(received %d, expected %d)", __func__, key->type, pktype); goto done; } if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { logit("Refusing RSA key because client uses unsafe " "signature scheme"); goto done; } fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); if (auth2_userkey_already_used(authctxt, key)) { logit("refusing previously-used %s key", key_type(key)); goto done; } if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, 0) != 1) { logit("%s: key type %s not in PubkeyAcceptedKeyTypes", __func__, sshkey_ssh_name(key)); goto done; } if (have_sig) { debug3("%s: have signature for %s %s", __func__, sshkey_type(key), fp); 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); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); buffer_put_cstring(&b, userstyle); free(userstyle); 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 pubkey_auth_info(authctxt, key, NULL); /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) { authenticated = 1; /* Record the successful key to prevent reuse */ auth2_record_userkey(authctxt, key); key = NULL; /* Don't free below */ } buffer_free(&b); free(sig); } else { debug("%s: test whether pkalg/pkblob are acceptable for %s %s", __func__, sshkey_type(key), fp); 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, 0))) { 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("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); if (key != NULL) key_free(key); free(pkalg); free(pkblob); free(fp); return authenticated; } void pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) { char *fp, *extra; va_list ap; int i; extra = NULL; if (fmt != NULL) { va_start(ap, fmt); i = vasprintf(&extra, fmt, ap); va_end(ap); if (i < 0 || extra == NULL) fatal("%s: vasprintf failed", __func__); } if (key_is_cert(key)) { fp = sshkey_fingerprint(key->cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT); auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", key_type(key), key->cert->key_id, (unsigned long long)key->cert->serial, key_type(key->cert->signature_key), fp == NULL ? "(null)" : fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } else { fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); auth_info(authctxt, "%s %s%s%s", key_type(key), fp == NULL ? "(null)" : fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } free(extra); } /* * Splits 's' into an argument vector. Handles quoted string and basic * escape characters (\\, \", \'). Caller must free the argument vector * and its members. */ static int split_argv(const char *s, int *argcp, char ***argvp) { int r = SSH_ERR_INTERNAL_ERROR; int argc = 0, quote, i, j; char *arg, **argv = xcalloc(1, sizeof(*argv)); *argvp = NULL; *argcp = 0; for (i = 0; s[i] != '\0'; i++) { /* Skip leading whitespace */ if (s[i] == ' ' || s[i] == '\t') continue; /* Start of a token */ quote = 0; if (s[i] == '\\' && (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\')) i++; else if (s[i] == '\'' || s[i] == '"') quote = s[i++]; argv = xreallocarray(argv, (argc + 2), sizeof(*argv)); arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1); argv[argc] = NULL; /* Copy the token in, removing escapes */ for (j = 0; s[i] != '\0'; i++) { if (s[i] == '\\') { if (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\') { i++; /* Skip '\' */ arg[j++] = s[i]; } else { /* Unrecognised escape */ arg[j++] = s[i]; } } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t')) break; /* done */ else if (quote != 0 && s[i] == quote) break; /* done */ else arg[j++] = s[i]; } if (s[i] == '\0') { if (quote != 0) { /* Ran out of string looking for close quote */ r = SSH_ERR_INVALID_FORMAT; goto out; } break; } } /* Success */ *argcp = argc; *argvp = argv; argc = 0; argv = NULL; r = 0; out: if (argc != 0 && argv != NULL) { for (i = 0; i < argc; i++) free(argv[i]); free(argv); } return r; } /* * Reassemble an argument vector into a string, quoting and escaping as * necessary. Caller must free returned string. */ static char * assemble_argv(int argc, char **argv) { int i, j, ws, r; char c, *ret; struct sshbuf *buf, *arg; if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); for (i = 0; i < argc; i++) { ws = 0; sshbuf_reset(arg); for (j = 0; argv[i][j] != '\0'; j++) { r = 0; c = argv[i][j]; switch (c) { case ' ': case '\t': ws = 1; r = sshbuf_put_u8(arg, c); break; case '\\': case '\'': case '"': if ((r = sshbuf_put_u8(arg, '\\')) != 0) break; /* FALLTHROUGH */ default: r = sshbuf_put_u8(arg, c); break; } if (r != 0) fatal("%s: sshbuf_put_u8: %s", __func__, ssh_err(r)); } if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || (r = sshbuf_putb(buf, arg)) != 0 || (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) fatal("%s: malloc failed", __func__); memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); ret[sshbuf_len(buf)] = '\0'; sshbuf_free(buf); sshbuf_free(arg); return ret; } /* * Runs command in a subprocess. Returns pid on success and a FILE* to the * subprocess' stdout or 0 on failure. * NB. "command" is only used for logging. */ static pid_t subprocess(const char *tag, struct passwd *pw, const char *command, int ac, char **av, FILE **child) { FILE *f; struct stat st; int devnull, p[2], i; pid_t pid; char *cp, errmsg[512]; u_int envsize; char **child_env; *child = NULL; debug3("%s: %s command \"%s\" running as %s", __func__, tag, command, pw->pw_name); /* Verify the path exists and is safe-ish to execute */ if (*av[0] != '/') { error("%s path is not absolute", tag); return 0; } temporarily_use_uid(pw); if (stat(av[0], &st) < 0) { error("Could not stat %s \"%s\": %s", tag, av[0], strerror(errno)); restore_uid(); return 0; } if (auth_secure_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); restore_uid(); return 0; } /* * Run the command; stderr is left in place, stdout is the * authorized_keys output. */ if (pipe(p) != 0) { error("%s: pipe: %s", tag, strerror(errno)); restore_uid(); return 0; } /* * Don't want to call this in the child, where it can fatal() and * run cleanup_exit() code. */ restore_uid(); switch ((pid = fork())) { case -1: /* error */ error("%s: fork: %s", tag, strerror(errno)); close(p[0]); close(p[1]); return 0; case 0: /* child */ /* Prepare a minimal environment for the child. */ envsize = 5; child_env = xcalloc(sizeof(*child_env), envsize); child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH); child_set_env(&child_env, &envsize, "USER", pw->pw_name); child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&child_env, &envsize, "HOME", pw->pw_dir); if ((cp = getenv("LANG")) != NULL) child_set_env(&child_env, &envsize, "LANG", cp); for (i = 0; i < NSIG; i++) signal(i, SIG_DFL); if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { error("%s: open %s: %s", tag, _PATH_DEVNULL, strerror(errno)); _exit(1); } /* Keep stderr around a while longer to catch errors */ if (dup2(devnull, STDIN_FILENO) == -1 || dup2(p[1], STDOUT_FILENO) == -1) { error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } closefrom(STDERR_FILENO + 1); /* Don't use permanently_set_uid() here to avoid fatal() */ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, strerror(errno)); _exit(1); } if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, strerror(errno)); _exit(1); } /* stdin is pointed to /dev/null at this point */ if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) { error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } execve(av[0], av, child_env); error("%s exec \"%s\": %s", tag, command, strerror(errno)); _exit(127); default: /* parent */ break; } close(p[1]); if ((f = fdopen(p[0], "r")) == NULL) { error("%s: fdopen: %s", tag, strerror(errno)); close(p[0]); /* Don't leave zombie child */ kill(pid, SIGTERM); while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) ; return 0; } /* Success */ debug3("%s: %s pid %ld", __func__, tag, (long)pid); *child = f; return pid; } /* Returns 0 if pid exited cleanly, non-zero otherwise */ static int exited_cleanly(pid_t pid, const char *tag, const char *cmd) { int status; while (waitpid(pid, &status, 0) == -1) { if (errno != EINTR) { error("%s: waitpid: %s", tag, strerror(errno)); return -1; } } if (WIFSIGNALED(status)) { error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status)); return -1; } else if (WEXITSTATUS(status) != 0) { error("%s %s failed, status %d", tag, cmd, WEXITSTATUS(status)); return -1; } return 0; } static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { char *result; u_int i; /* XXX percent_expand() sequences for authorized_principals? */ for (i = 0; i < cert->nprincipals; i++) { if ((result = match_list(cert->principals[i], principal_list, NULL)) != NULL) { debug3("matched principal from key options \"%.100s\"", result); free(result); return 1; } } return 0; } static int process_principals(FILE *f, char *file, struct passwd *pw, struct sshkey_cert *cert) { char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; u_long linenum = 0; u_int i; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { /* Skip leading whitespace. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; /* Skip blank and comment lines. */ if ((ep = strchr(cp, '#')) != NULL) *ep = '\0'; if (!*cp || *cp == '\n') continue; /* Trim trailing whitespace. */ ep = cp + strlen(cp) - 1; while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t')) *ep-- = '\0'; /* * If the line has internal whitespace then assume it has * key options. */ line_opts = NULL; if ((ep = strrchr(cp, ' ')) != NULL || (ep = strrchr(cp, '\t')) != NULL) { for (; *ep == ' ' || *ep == '\t'; ep++) ; line_opts = cp; cp = ep; } for (i = 0; i < cert->nprincipals; i++) { if (strcmp(cp, cert->principals[i]) == 0) { debug3("%s:%lu: matched principal \"%.100s\"", file == NULL ? "(command)" : file, linenum, cert->principals[i]); if (auth_parse_options(pw, line_opts, file, linenum) != 1) continue; return 1; } } } return 0; } static int match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) { FILE *f; int success; temporarily_use_uid(pw); debug("trying authorized principals file %s", file); if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { restore_uid(); return 0; } success = process_principals(f, file, pw, cert); fclose(f); restore_uid(); return success; } /* * Checks whether principal is allowed in output of command. * returns 1 if the principal is allowed or 0 otherwise. */ static int match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) { FILE *f = NULL; int ok, found_principal = 0; struct passwd *pw; int i, ac = 0, uid_swapped = 0; pid_t pid; char *tmp, *username = NULL, *command = NULL, **av = NULL; void (*osigchld)(int); if (options.authorized_principals_command == NULL) return 0; if (options.authorized_principals_command_user == NULL) { error("No user for AuthorizedPrincipalsCommand specified, " "skipping"); return 0; } /* * NB. all returns later this function should go via "out" to * ensure the original SIGCHLD handler is restored properly. */ osigchld = signal(SIGCHLD, SIG_DFL); /* Prepare and verify the user for the command */ username = percent_expand(options.authorized_principals_command_user, "u", user_pw->pw_name, (char *)NULL); pw = getpwnam(username); if (pw == NULL) { error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s", username, strerror(errno)); goto out; } /* Turn the command into an argument vector */ if (split_argv(options.authorized_principals_command, &ac, &av) != 0) { error("AuthorizedPrincipalsCommand \"%s\" contains " "invalid quotes", command); goto out; } if (ac == 0) { error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments", command); goto out; } for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], "u", user_pw->pw_name, "h", user_pw->pw_dir, (char *)NULL); if (tmp == NULL) fatal("%s: percent_expand failed", __func__); free(av[i]); av[i] = tmp; } /* Prepare a printable command for logs, etc. */ command = assemble_argv(ac, av); if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command, ac, av, &f)) == 0) goto out; uid_swapped = 1; temporarily_use_uid(pw); ok = process_principals(f, NULL, pw, cert); if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) goto out; /* Read completed successfully */ found_principal = ok; out: if (f != NULL) fclose(f); signal(SIGCHLD, osigchld); for (i = 0; i < ac; i++) free(av[i]); free(av); if (uid_swapped) restore_uid(); free(command); free(username); return found_principal; } /* * Checks whether key is allowed in authorized_keys-format file, * returns 1 if the key is allowed or 0 otherwise. */ static int check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) { char line[SSH_MAX_PUBKEY_BYTES]; const char *reason; int found_key = 0; u_long linenum = 0; Key *found; char *fp; found_key = 0; found = NULL; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { char *cp, *key_options = NULL; if (found != NULL) key_free(found); found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); auth_clear_options(); /* 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_is_cert(key)) { if (!key_equal(found, key->cert->signature_key)) continue; if (auth_parse_options(pw, key_options, file, linenum) != 1) continue; if (!key_is_cert_authority) continue; if ((fp = sshkey_fingerprint(found, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) continue; debug("matching CA found: file %s, line %lu, %s %s", file, linenum, key_type(found), fp); /* * If the user has specified a list of principals as * a key option, then prefer that list to matching * their username in the certificate principals list. */ if (authorized_principals != NULL && !match_principals_option(authorized_principals, key->cert)) { reason = "Certificate does not contain an " "authorized principal"; fail_reason: free(fp); error("%s", reason); auth_debug_add("%s", reason); continue; } if (key_cert_check_authority(key, 0, 0, authorized_principals == NULL ? pw->pw_name : NULL, &reason) != 0) goto fail_reason; if (auth_cert_options(key, pw) != 0) { free(fp); continue; } verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by %s CA %s via %s", key->cert->key_id, (unsigned long long)key->cert->serial, key_type(found), fp, file); free(fp); found_key = 1; break; } else if (key_equal(found, key)) { if (auth_parse_options(pw, key_options, file, linenum) != 1) continue; if (key_is_cert_authority) continue; if ((fp = sshkey_fingerprint(found, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(found), fp); free(fp); found_key = 1; break; } } if (found != NULL) key_free(found); if (!found_key) debug2("key not found"); return found_key; } /* Authenticate a certificate key against TrustedUserCAKeys */ static int user_cert_trusted_ca(struct passwd *pw, Key *key) { char *ca_fp, *principals_file = NULL; const char *reason; int ret = 0, found_principal = 0, use_authorized_principals; if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) return 0; if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) return 0; if (sshkey_in_file(key->cert->signature_key, options.trusted_user_ca_keys, 1, 0) != 0) { debug2("%s: CA %s %s is not listed in %s", __func__, key_type(key->cert->signature_key), ca_fp, options.trusted_user_ca_keys); goto out; } /* * If AuthorizedPrincipals is in use, then compare the certificate * principals against the names in that file rather than matching * against the username. */ if ((principals_file = authorized_principals_file(pw)) != NULL) { if (match_principals_file(principals_file, pw, key->cert)) found_principal = 1; } /* Try querying command if specified */ if (!found_principal && match_principals_command(pw, key->cert)) found_principal = 1; /* If principals file or command is specified, then require a match */ use_authorized_principals = principals_file != NULL || options.authorized_principals_command != NULL; if (!found_principal && use_authorized_principals) { reason = "Certificate does not contain an authorized principal"; fail_reason: error("%s", reason); auth_debug_add("%s", reason); goto out; } if (key_cert_check_authority(key, 0, 1, use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) goto fail_reason; if (auth_cert_options(key, pw) != 0) goto out; verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " "%s CA %s via %s", key->cert->key_id, (unsigned long long)key->cert->serial, key_type(key->cert->signature_key), ca_fp, options.trusted_user_ca_keys); ret = 1; out: free(principals_file); free(ca_fp); return ret; } /* * Checks whether key is allowed in file. * returns 1 if the key is allowed or 0 otherwise. */ static int user_key_allowed2(struct passwd *pw, Key *key, char *file) { FILE *f; int found_key = 0; /* Temporarily use the user's uid. */ temporarily_use_uid(pw); debug("trying public key file %s", file); if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { found_key = check_authkeys_file(f, file, key, pw); fclose(f); } restore_uid(); return found_key; } /* * Checks whether key is allowed in output of command. * returns 1 if the key is allowed or 0 otherwise. */ static int user_key_command_allowed2(struct passwd *user_pw, Key *key) { FILE *f = NULL; int r, ok, found_key = 0; struct passwd *pw; int i, uid_swapped = 0, ac = 0; pid_t pid; char *username = NULL, *key_fp = NULL, *keytext = NULL; char *tmp, *command = NULL, **av = NULL; void (*osigchld)(int); if (options.authorized_keys_command == NULL) return 0; if (options.authorized_keys_command_user == NULL) { error("No user for AuthorizedKeysCommand specified, skipping"); return 0; } /* * NB. all returns later this function should go via "out" to * ensure the original SIGCHLD handler is restored properly. */ osigchld = signal(SIGCHLD, SIG_DFL); /* Prepare and verify the user for the command */ username = percent_expand(options.authorized_keys_command_user, "u", user_pw->pw_name, (char *)NULL); pw = getpwnam(username); if (pw == NULL) { error("AuthorizedKeysCommandUser \"%s\" not found: %s", username, strerror(errno)); goto out; } /* Prepare AuthorizedKeysCommand */ if ((key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; } if ((r = sshkey_to_base64(key, &keytext)) != 0) { error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); goto out; } /* Turn the command into an argument vector */ if (split_argv(options.authorized_keys_command, &ac, &av) != 0) { error("AuthorizedKeysCommand \"%s\" contains invalid quotes", command); goto out; } if (ac == 0) { error("AuthorizedKeysCommand \"%s\" yielded no arguments", command); goto out; } for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", sshkey_ssh_name(key), "f", key_fp, "k", keytext, (char *)NULL); if (tmp == NULL) fatal("%s: percent_expand failed", __func__); free(av[i]); av[i] = tmp; } /* Prepare a printable command for logs, etc. */ command = assemble_argv(ac, av); /* * If AuthorizedKeysCommand was run without arguments * then fall back to the old behaviour of passing the * target username as a single argument. */ if (ac == 1) { av = xreallocarray(av, ac + 2, sizeof(*av)); av[1] = xstrdup(user_pw->pw_name); av[2] = NULL; /* Fix up command too, since it is used in log messages */ free(command); xasprintf(&command, "%s %s", av[0], av[1]); } if ((pid = subprocess("AuthorizedKeysCommand", pw, command, ac, av, &f)) == 0) goto out; uid_swapped = 1; temporarily_use_uid(pw); ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) goto out; /* Read completed successfully */ found_key = ok; out: if (f != NULL) fclose(f); signal(SIGCHLD, osigchld); for (i = 0; i < ac; i++) free(av[i]); free(av); if (uid_swapped) restore_uid(); free(command); free(username); free(key_fp); free(keytext); return found_key; } /* * Check whether key authenticates and authorises the user. */ int user_key_allowed(struct passwd *pw, Key *key, int auth_attempt) { u_int success, i; char *file; if (auth_key_is_revoked(key)) return 0; if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) return 0; success = user_cert_trusted_ca(pw, key); if (success) return success; success = user_key_command_allowed2(pw, key); if (success > 0) return success; for (i = 0; !success && i < options.num_authkeys_files; i++) { if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); success = user_key_allowed2(pw, key, file); free(file); } return success; } /* Records a public key in the list of previously-successful keys */ void auth2_record_userkey(Authctxt *authctxt, struct sshkey *key) { struct sshkey **tmp; if (authctxt->nprev_userkeys >= INT_MAX || (tmp = reallocarray(authctxt->prev_userkeys, authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL) fatal("%s: reallocarray failed", __func__); authctxt->prev_userkeys = tmp; authctxt->prev_userkeys[authctxt->nprev_userkeys] = key; authctxt->nprev_userkeys++; } /* Checks whether a key has already been used successfully for authentication */ int auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key) { u_int i; for (i = 0; i < authctxt->nprev_userkeys; i++) { if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) { return 1; } } return 0; } Authmethod method_pubkey = { "publickey", userauth_pubkey, &options.pubkey_authentication }; openssh-7.2p2/auth2.c010064400017500001750000000377051267006270000126550ustar00djmdjm/* $OpenBSD: auth2.c,v 1.135 2015/01/19 20:07:45 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. */ #include "includes.h" #include #include #include #include #include #include #include #include #include "atomicio.h" #include "xmalloc.h" #include "ssh2.h" #include "packet.h" #include "log.h" #include "buffer.h" #include "misc.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 int input_service_request(int, u_int32_t, void *); static int input_userauth_request(int, u_int32_t, void *); /* helper */ static Authmethod *authmethod_lookup(Authctxt *, const char *); static char *authmethods_get(Authctxt *authctxt); #define MATCH_NONE 0 /* method or submethod mismatch */ #define MATCH_METHOD 1 /* method matches (no submethod specified) */ #define MATCH_BOTH 2 /* method and submethod match */ #define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */ static int list_starts_with(const char *, const char *, const char *); 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 <= 0 || 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) { free(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) != 0) return; if ((banner = PRIVSEP(auth2_read_banner())) == NULL) goto done; userauth_send_banner(banner); done: free(banner); } /* * loop until authctxt->success == TRUE */ void do_authentication2(Authctxt *authctxt) { dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); } /*ARGSUSED*/ static int input_service_request(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; u_int len; int acceptit = 0; char *service = packet_get_cstring(&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); } free(service); return 0; } /*ARGSUSED*/ static int 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_cstring(NULL); service = packet_get_cstring(NULL); method = packet_get_cstring(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); userauth_banner(); if (auth2_setup_methods_lists(authctxt) != 0) packet_disconnect("no authentication methods enabled"); } 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 /* XXX move to auth2_gssapi_stop() */ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); #endif authctxt->postponed = 0; authctxt->server_caused_failure = 0; /* try to authenticate user */ m = authmethod_lookup(authctxt, method); if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); } userauth_finish(authctxt, authenticated, method, NULL); free(service); free(user); free(method); return 0; } void userauth_finish(Authctxt *authctxt, int authenticated, const char *method, const char *submethod) { char *methods; int partial = 0; if (!authctxt->valid && authenticated) fatal("INTERNAL ERROR: authenticated invalid user %s", authctxt->user); if (authenticated && authctxt->postponed) fatal("INTERNAL ERROR: authenticated and postponed"); /* 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 } if (authenticated && options.num_auth_methods != 0) { if (!auth2_update_methods_lists(authctxt, method, submethod)) { authenticated = 0; partial = 1; } } /* Log before sending the reply */ auth_log(authctxt, authenticated, partial, method, submethod); if (authctxt->postponed) return; #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 */ 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 { /* Allow initial try of "none" auth without failure penalty */ if (!partial && !authctxt->server_caused_failure && (authctxt->attempt > 1 || strcmp(method, "none") != 0)) authctxt->failures++; if (authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif auth_maxtries_exceeded(authctxt); } methods = authmethods_get(authctxt); debug3("%s: failure partial=%d next methods=\"%s\"", __func__, partial, methods); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); packet_put_char(partial); packet_send(); packet_write_wait(); free(methods); } } /* * Checks whether method is allowed by at least one AuthenticationMethods * methods list. Returns 1 if allowed, or no methods lists configured. * 0 otherwise. */ int auth2_method_allowed(Authctxt *authctxt, const char *method, const char *submethod) { u_int i; /* * NB. authctxt->num_auth_methods might be zero as a result of * auth2_setup_methods_lists(), so check the configuration. */ if (options.num_auth_methods == 0) return 1; for (i = 0; i < authctxt->num_auth_methods; i++) { if (list_starts_with(authctxt->auth_methods[i], method, submethod) != MATCH_NONE) return 1; } return 0; } static char * authmethods_get(Authctxt *authctxt) { Buffer b; char *list; u_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) continue; if (!auth2_method_allowed(authctxt, authmethods[i]->name, NULL)) continue; 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(Authctxt *authctxt, 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 && auth2_method_allowed(authctxt, authmethods[i]->name, NULL)) return authmethods[i]; debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); return NULL; } /* * Check a comma-separated list of methods for validity. Is need_enable is * non-zero, then also require that the methods are enabled. * Returns 0 on success or -1 if the methods list is invalid. */ int auth2_methods_valid(const char *_methods, int need_enable) { char *methods, *omethods, *method, *p; u_int i, found; int ret = -1; if (*_methods == '\0') { error("empty authentication method list"); return -1; } omethods = methods = xstrdup(_methods); while ((method = strsep(&methods, ",")) != NULL) { for (found = i = 0; !found && authmethods[i] != NULL; i++) { if ((p = strchr(method, ':')) != NULL) *p = '\0'; if (strcmp(method, authmethods[i]->name) != 0) continue; if (need_enable) { if (authmethods[i]->enabled == NULL || *(authmethods[i]->enabled) == 0) { error("Disabled method \"%s\" in " "AuthenticationMethods list \"%s\"", method, _methods); goto out; } } found = 1; break; } if (!found) { error("Unknown authentication method \"%s\" in list", method); goto out; } } ret = 0; out: free(omethods); return ret; } /* * Prune the AuthenticationMethods supplied in the configuration, removing * any methods lists that include disabled methods. Note that this might * leave authctxt->num_auth_methods == 0, even when multiple required auth * has been requested. For this reason, all tests for whether multiple is * enabled should consult options.num_auth_methods directly. */ int auth2_setup_methods_lists(Authctxt *authctxt) { u_int i; if (options.num_auth_methods == 0) return 0; debug3("%s: checking methods", __func__); authctxt->auth_methods = xcalloc(options.num_auth_methods, sizeof(*authctxt->auth_methods)); authctxt->num_auth_methods = 0; for (i = 0; i < options.num_auth_methods; i++) { if (auth2_methods_valid(options.auth_methods[i], 1) != 0) { logit("Authentication methods list \"%s\" contains " "disabled method, skipping", options.auth_methods[i]); continue; } debug("authentication methods list %d: %s", authctxt->num_auth_methods, options.auth_methods[i]); authctxt->auth_methods[authctxt->num_auth_methods++] = xstrdup(options.auth_methods[i]); } if (authctxt->num_auth_methods == 0) { error("No AuthenticationMethods left after eliminating " "disabled methods"); return -1; } return 0; } static int list_starts_with(const char *methods, const char *method, const char *submethod) { size_t l = strlen(method); int match; const char *p; if (strncmp(methods, method, l) != 0) return MATCH_NONE; p = methods + l; match = MATCH_METHOD; if (*p == ':') { if (!submethod) return MATCH_PARTIAL; l = strlen(submethod); p += 1; if (strncmp(submethod, p, l)) return MATCH_NONE; p += l; match = MATCH_BOTH; } if (*p != ',' && *p != '\0') return MATCH_NONE; return match; } /* * Remove method from the start of a comma-separated list of methods. * Returns 0 if the list of methods did not start with that method or 1 * if it did. */ static int remove_method(char **methods, const char *method, const char *submethod) { char *omethods = *methods, *p; size_t l = strlen(method); int match; match = list_starts_with(omethods, method, submethod); if (match != MATCH_METHOD && match != MATCH_BOTH) return 0; p = omethods + l; if (submethod && match == MATCH_BOTH) p += 1 + strlen(submethod); /* include colon */ if (*p == ',') p++; *methods = xstrdup(p); free(omethods); return 1; } /* * Called after successful authentication. Will remove the successful method * from the start of each list in which it occurs. If it was the last method * in any list, then authentication is deemed successful. * Returns 1 if the method completed any authentication list or 0 otherwise. */ int auth2_update_methods_lists(Authctxt *authctxt, const char *method, const char *submethod) { u_int i, found = 0; debug3("%s: updating methods list after \"%s\"", __func__, method); for (i = 0; i < authctxt->num_auth_methods; i++) { if (!remove_method(&(authctxt->auth_methods[i]), method, submethod)) continue; found = 1; if (*authctxt->auth_methods[i] == '\0') { debug2("authentication methods list %d complete", i); return 1; } debug3("authentication methods list %d remaining: \"%s\"", i, authctxt->auth_methods[i]); } /* This should not happen, but would be bad if it did */ if (!found) fatal("%s: method not in AuthenticationMethods", __func__); return 0; } openssh-7.2p2/authfd.c010064400017500001750000000436571267006270000131100ustar00djmdjm/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssh.h" #include "rsa.h" #include "sshbuf.h" #include "sshkey.h" #include "authfd.h" #include "cipher.h" #include "compat.h" #include "log.h" #include "atomicio.h" #include "misc.h" #include "ssherr.h" #define MAX_AGENT_IDENTITIES 2048 /* Max keys in agent reply */ #define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */ /* macro to check for "agent failure" message */ #define agent_failed(x) \ ((x == SSH_AGENT_FAILURE) || \ (x == SSH_COM_AGENT2_FAILURE) || \ (x == SSH2_AGENT_FAILURE)) /* Convert success/failure response from agent to a err.h status */ static int decode_reply(u_char type) { if (agent_failed(type)) return SSH_ERR_AGENT_FAILURE; else if (type == SSH_AGENT_SUCCESS) return 0; else return SSH_ERR_INVALID_FORMAT; } /* Returns the number of the authentication fd, or -1 if there is none. */ int ssh_get_authentication_socket(int *fdp) { const char *authsocket; int sock, oerrno; struct sockaddr_un sunaddr; if (fdp != NULL) *fdp = -1; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); if (!authsocket) return SSH_ERR_AGENT_NOT_PRESENT; memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) return SSH_ERR_SYSTEM_ERROR; /* close on exec */ if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 || connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { oerrno = errno; close(sock); errno = oerrno; return SSH_ERR_SYSTEM_ERROR; } if (fdp != NULL) *fdp = sock; else close(sock); return 0; } /* Communicate with agent: send request and read reply */ static int ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) { int r; size_t l, len; char buf[1024]; /* Get the length of the message, and format it in the buffer. */ len = sshbuf_len(request); put_u32(buf, len); /* Send the length and then the packet to the agent. */ if (atomicio(vwrite, sock, buf, 4) != 4 || atomicio(vwrite, sock, (u_char *)sshbuf_ptr(request), sshbuf_len(request)) != sshbuf_len(request)) return SSH_ERR_AGENT_COMMUNICATION; /* * Wait for response from the agent. First read the length of the * response packet. */ if (atomicio(read, sock, buf, 4) != 4) return SSH_ERR_AGENT_COMMUNICATION; /* Extract the length, and check it for sanity. */ len = get_u32(buf); if (len > MAX_AGENT_REPLY_LEN) return SSH_ERR_INVALID_FORMAT; /* Read the rest of the response in to the buffer. */ sshbuf_reset(reply); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); if (atomicio(read, sock, buf, l) != l) return SSH_ERR_AGENT_COMMUNICATION; if ((r = sshbuf_put(reply, buf, l)) != 0) return r; len -= l; } return 0; } /* * 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); } /* Lock/unlock agent */ int ssh_lock_agent(int sock, int lock, const char *password) { int r; u_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK; struct sshbuf *msg; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, type)) != 0 || (r = sshbuf_put_cstring(msg, password)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; r = decode_reply(type); out: sshbuf_free(msg); return r; } #ifdef WITH_SSH1 static int deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp) { struct sshkey *key; int r, keybits; u_int32_t bits; char *comment = NULL; if ((key = sshkey_new(KEY_RSA1)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_get_u32(ids, &bits)) != 0 || (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) goto out; keybits = BN_num_bits(key->rsa->n); /* XXX previously we just warned here. I think we should be strict */ if (keybits < 0 || bits != (u_int)keybits) { r = SSH_ERR_KEY_BITS_MISMATCH; goto out; } if (keyp != NULL) { *keyp = key; key = NULL; } if (commentp != NULL) { *commentp = comment; comment = NULL; } r = 0; out: sshkey_free(key); free(comment); return r; } #endif static int deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) { int r; char *comment = NULL; const u_char *blob; size_t blen; if ((r = sshbuf_get_string_direct(ids, &blob, &blen)) != 0 || (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) goto out; if ((r = sshkey_from_blob(blob, blen, keyp)) != 0) goto out; if (commentp != NULL) { *commentp = comment; comment = NULL; } r = 0; out: free(comment); return r; } /* * Fetch list of identities held by the agent. */ int ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp) { u_char type, code1 = 0, code2 = 0; u_int32_t num, i; struct sshbuf *msg; struct ssh_identitylist *idl = NULL; int r; /* Determine request and expected response types */ 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 SSH_ERR_INVALID_ARGUMENT; } /* * Send a message to the agent requesting for a list of the * identities it can represent. */ if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, code1)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; /* Get message type, and verify that we got a proper answer. */ if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; if (agent_failed(type)) { r = SSH_ERR_AGENT_FAILURE; goto out; } else if (type != code2) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* Get the number of entries in the response and check it for sanity. */ if ((r = sshbuf_get_u32(msg, &num)) != 0) goto out; if (num > MAX_AGENT_IDENTITIES) { r = SSH_ERR_INVALID_FORMAT; goto out; } if (num == 0) { r = SSH_ERR_AGENT_NO_IDENTITIES; goto out; } /* Deserialise the response into a list of keys/comments */ if ((idl = calloc(1, sizeof(*idl))) == NULL || (idl->keys = calloc(num, sizeof(*idl->keys))) == NULL || (idl->comments = calloc(num, sizeof(*idl->comments))) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } for (i = 0; i < num;) { switch (version) { case 1: #ifdef WITH_SSH1 if ((r = deserialise_identity1(msg, &(idl->keys[i]), &(idl->comments[i]))) != 0) goto out; #endif break; case 2: if ((r = deserialise_identity2(msg, &(idl->keys[i]), &(idl->comments[i]))) != 0) { if (r == SSH_ERR_KEY_TYPE_UNKNOWN) { /* Gracefully skip unknown key types */ num--; continue; } else goto out; } break; } i++; } idl->nkeys = num; *idlp = idl; idl = NULL; r = 0; out: sshbuf_free(msg); if (idl != NULL) ssh_free_identitylist(idl); return r; } void ssh_free_identitylist(struct ssh_identitylist *idl) { size_t i; if (idl == NULL) return; for (i = 0; i < idl->nkeys; i++) { if (idl->keys != NULL) sshkey_free(idl->keys[i]); if (idl->comments != NULL) free(idl->comments[i]); } free(idl); } /* * Sends a challenge (typically from a server via ssh(1)) to the agent, * and waits for a response from the agent. * Returns true (non-zero) if the agent gave the correct answer, zero * otherwise. */ #ifdef WITH_SSH1 int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, u_char session_id[16], u_char response[16]) { struct sshbuf *msg; int r; u_char type; if (key->type != KEY_RSA1) return SSH_ERR_INVALID_ARGUMENT; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || (r = sshbuf_put_bignum1(msg, challenge)) != 0 || (r = sshbuf_put(msg, session_id, 16)) != 0 || (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; if (agent_failed(type)) { r = SSH_ERR_AGENT_FAILURE; goto out; } else if (type != SSH_AGENT_RSA_RESPONSE) { r = SSH_ERR_INVALID_FORMAT; goto out; } if ((r = sshbuf_get(msg, response, 16)) != 0) goto out; r = 0; out: sshbuf_free(msg); return r; } #endif /* encode signature algoritm in flag bits, so we can keep the msg format */ static u_int agent_encode_alg(struct sshkey *key, const char *alg) { if (alg != NULL && key->type == KEY_RSA) { if (strcmp(alg, "rsa-sha2-256") == 0) return SSH_AGENT_RSA_SHA2_256; else if (strcmp(alg, "rsa-sha2-512") == 0) return SSH_AGENT_RSA_SHA2_512; } return 0; } /* ask agent to sign data, returns err.h code on error, 0 on success */ int ssh_agent_sign(int sock, struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *alg, u_int compat) { struct sshbuf *msg; u_char *blob = NULL, type; size_t blen = 0, len = 0; u_int flags = 0; int r = SSH_ERR_INTERNAL_ERROR; *sigp = NULL; *lenp = 0; if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; if (compat & SSH_BUG_SIGBLOB) flags |= SSH_AGENT_OLD_SIGNATURE; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) goto out; flags |= agent_encode_alg(key, alg); if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || (r = sshbuf_put_string(msg, blob, blen)) != 0 || (r = sshbuf_put_string(msg, data, datalen)) != 0 || (r = sshbuf_put_u32(msg, flags)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; if (agent_failed(type)) { r = SSH_ERR_AGENT_FAILURE; goto out; } else if (type != SSH2_AGENT_SIGN_RESPONSE) { r = SSH_ERR_INVALID_FORMAT; goto out; } if ((r = sshbuf_get_string(msg, sigp, &len)) != 0) goto out; *lenp = len; r = 0; out: if (blob != NULL) { explicit_bzero(blob, blen); free(blob); } sshbuf_free(msg); return r; } /* Encode key for a message to the agent. */ #ifdef WITH_SSH1 static int ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) { int r; /* To keep within the protocol: p < q for ssh. in SSL p > q */ if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 || (r = sshbuf_put_bignum1(b, key->n)) != 0 || (r = sshbuf_put_bignum1(b, key->e)) != 0 || (r = sshbuf_put_bignum1(b, key->d)) != 0 || (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || (r = sshbuf_put_bignum1(b, key->q)) != 0 || (r = sshbuf_put_bignum1(b, key->p)) != 0 || (r = sshbuf_put_cstring(b, comment)) != 0) return r; return 0; } #endif static int ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, const char *comment) { int r; if ((r = sshkey_private_serialize(key, b)) != 0 || (r = sshbuf_put_cstring(b, comment)) != 0) return r; return 0; } static int encode_constraints(struct sshbuf *m, u_int life, u_int confirm) { int r; if (life != 0) { if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_LIFETIME)) != 0 || (r = sshbuf_put_u32(m, life)) != 0) goto out; } if (confirm != 0) { if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_CONFIRM)) != 0) goto out; } r = 0; out: return r; } /* * Adds an identity to the authentication server. * This call is intended only for use by ssh-add(1) and like applications. */ int ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment, u_int life, u_int confirm) { struct sshbuf *msg; int r, constrained = (life || confirm); u_char type; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; switch (key->type) { #ifdef WITH_SSH1 case KEY_RSA1: type = constrained ? SSH_AGENTC_ADD_RSA_ID_CONSTRAINED : SSH_AGENTC_ADD_RSA_IDENTITY; if ((r = sshbuf_put_u8(msg, type)) != 0 || (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0) goto out; break; #endif #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: case KEY_DSA: case KEY_DSA_CERT: case KEY_ECDSA: case KEY_ECDSA_CERT: #endif case KEY_ED25519: case KEY_ED25519_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; if ((r = sshbuf_put_u8(msg, type)) != 0 || (r = ssh_encode_identity_ssh2(msg, key, comment)) != 0) goto out; break; default: r = SSH_ERR_INVALID_ARGUMENT; goto out; } if (constrained && (r = encode_constraints(msg, life, confirm)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; r = decode_reply(type); out: sshbuf_free(msg); return r; } /* * Removes an identity from the authentication server. * This call is intended only for use by ssh-add(1) and like applications. */ int ssh_remove_identity(int sock, struct sshkey *key) { struct sshbuf *msg; int r; u_char type, *blob = NULL; size_t blen; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; #ifdef WITH_SSH1 if (key->type == KEY_RSA1) { if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) goto out; } else #endif if (key->type != KEY_UNSPEC) { if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) goto out; if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_REMOVE_IDENTITY)) != 0 || (r = sshbuf_put_string(msg, blob, blen)) != 0) goto out; } else { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; r = decode_reply(type); out: if (blob != NULL) { explicit_bzero(blob, blen); free(blob); } sshbuf_free(msg); return r; } /* * Add/remove an token-based identity from the authentication server. * This call is intended only for use by ssh-add(1) and like applications. */ int ssh_update_card(int sock, int add, const char *reader_id, const char *pin, u_int life, u_int confirm) { struct sshbuf *msg; int r, constrained = (life || confirm); u_char type; if (add) { type = constrained ? SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED : SSH_AGENTC_ADD_SMARTCARD_KEY; } else type = SSH_AGENTC_REMOVE_SMARTCARD_KEY; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, type)) != 0 || (r = sshbuf_put_cstring(msg, reader_id)) != 0 || (r = sshbuf_put_cstring(msg, pin)) != 0) goto out; if (constrained && (r = encode_constraints(msg, life, confirm)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; r = decode_reply(type); out: sshbuf_free(msg); return r; } /* * Removes all identities from the agent. * This call is intended only for use by ssh-add(1) and like applications. */ int ssh_remove_all_identities(int sock, int version) { struct sshbuf *msg; u_char type = (version == 1) ? SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : SSH2_AGENTC_REMOVE_ALL_IDENTITIES; int r; if ((msg = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, type)) != 0) goto out; if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; r = decode_reply(type); out: sshbuf_free(msg); return r; } openssh-7.2p2/authfd.h010064400017500001750000000062031267006270000130770ustar00djmdjm/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 /* List of identities returned by ssh_fetch_identitylist() */ struct ssh_identitylist { size_t nkeys; struct sshkey **keys; char **comments; }; int ssh_get_authentication_socket(int *fdp); void ssh_close_authentication_socket(int sock); int ssh_lock_agent(int sock, int lock, const char *password); int ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp); void ssh_free_identitylist(struct ssh_identitylist *idl); int ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment, u_int life, u_int confirm); int ssh_remove_identity(int sock, struct sshkey *key); int ssh_update_card(int sock, int add, const char *reader_id, const char *pin, u_int life, u_int confirm); int ssh_remove_all_identities(int sock, int version); int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, u_char session_id[16], u_char response[16]); int ssh_agent_sign(int sock, struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *alg, u_int compat); /* 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 #define SSH_AGENT_RSA_SHA2_256 0x02 #define SSH_AGENT_RSA_SHA2_512 0x04 #endif /* AUTHFD_H */ openssh-7.2p2/authfile.c010064400017500001750000000332461267006270000134270ustar00djmdjm/* $OpenBSD: authfile.c,v 1.120 2015/12/11 04:21:11 mmcc Exp $ */ /* * Copyright (c) 2000, 2013 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 #include #include #include #include #include #include #include #include #include #include #include "cipher.h" #include "ssh.h" #include "log.h" #include "authfile.h" #include "rsa.h" #include "misc.h" #include "atomicio.h" #include "sshkey.h" #include "sshbuf.h" #include "ssherr.h" #include "krl.h" #define MAX_KEY_FILE_SIZE (1024 * 1024) /* Save a key blob to a file */ static int sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) { int fd, oerrno; if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) return SSH_ERR_SYSTEM_ERROR; if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf), sshbuf_len(keybuf)) != sshbuf_len(keybuf)) { oerrno = errno; close(fd); unlink(filename); errno = oerrno; return SSH_ERR_SYSTEM_ERROR; } close(fd); return 0; } int sshkey_save_private(struct sshkey *key, const char *filename, const char *passphrase, const char *comment, int force_new_format, const char *new_format_cipher, int new_format_rounds) { struct sshbuf *keyblob = NULL; int r; if ((keyblob = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, force_new_format, new_format_cipher, new_format_rounds)) != 0) goto out; if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) goto out; r = 0; out: sshbuf_free(keyblob); return r; } /* Load a key from a fd into a buffer */ int sshkey_load_file(int fd, struct sshbuf *blob) { u_char buf[1024]; size_t len; struct stat st; int r; if (fstat(fd, &st) < 0) return SSH_ERR_SYSTEM_ERROR; if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && st.st_size > MAX_KEY_FILE_SIZE) return SSH_ERR_INVALID_FORMAT; for (;;) { if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { if (errno == EPIPE) break; r = SSH_ERR_SYSTEM_ERROR; goto out; } if ((r = sshbuf_put(blob, buf, len)) != 0) goto out; if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) { r = SSH_ERR_INVALID_FORMAT; goto out; } } if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && st.st_size != (off_t)sshbuf_len(blob)) { r = SSH_ERR_FILE_CHANGED; goto out; } r = 0; out: explicit_bzero(buf, sizeof(buf)); if (r != 0) sshbuf_reset(blob); return r; } #ifdef WITH_SSH1 /* * 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 int sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp) { struct sshbuf *b = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_load_file(fd, b)) != 0) goto out; if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0) goto out; r = 0; out: sshbuf_free(b); return r; } #endif /* WITH_SSH1 */ /* XXX remove error() calls from here? */ int sshkey_perm_ok(int fd, const char *filename) { struct stat st; if (fstat(fd, &st) < 0) return SSH_ERR_SYSTEM_ERROR; /* * 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 required that your private key files are NOT accessible by others."); error("This private key will be ignored."); return SSH_ERR_KEY_BAD_PERMISSIONS; } return 0; } /* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */ int sshkey_load_private_type(int type, const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp, int *perm_ok) { int fd, r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((fd = open(filename, O_RDONLY)) < 0) { if (perm_ok != NULL) *perm_ok = 0; return SSH_ERR_SYSTEM_ERROR; } if (sshkey_perm_ok(fd, filename) != 0) { if (perm_ok != NULL) *perm_ok = 0; r = SSH_ERR_KEY_BAD_PERMISSIONS; goto out; } if (perm_ok != NULL) *perm_ok = 1; r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp); out: close(fd); return r; } int sshkey_load_private_type_fd(int fd, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r; if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_load_file(fd, buffer)) != 0 || (r = sshkey_parse_private_fileblob_type(buffer, type, passphrase, keyp, commentp)) != 0) goto out; /* success */ r = 0; out: sshbuf_free(buffer); return r; } /* XXX this is almost identical to sshkey_load_private_type() */ int sshkey_load_private(const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r, fd; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((fd = open(filename, O_RDONLY)) < 0) return SSH_ERR_SYSTEM_ERROR; if (sshkey_perm_ok(fd, filename) != 0) { r = SSH_ERR_KEY_BAD_PERMISSIONS; goto out; } if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_load_file(fd, buffer)) != 0 || (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp, commentp)) != 0) goto out; r = 0; out: close(fd); sshbuf_free(buffer); return r; } static int sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp) { FILE *f; char line[SSH_MAX_PUBKEY_BYTES]; char *cp; u_long linenum = 0; int r; if (commentp != NULL) *commentp = NULL; if ((f = fopen(filename, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; while (read_keyfile_line(f, filename, line, sizeof(line), &linenum) != -1) { cp = line; switch (*cp) { case '#': case '\n': case '\0': continue; } /* Abort loading if this looks like a private key */ if (strncmp(cp, "-----BEGIN", 10) == 0 || strcmp(cp, "SSH PRIVATE KEY FILE") == 0) break; /* Skip leading whitespace. */ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) ; if (*cp) { if ((r = sshkey_read(k, &cp)) == 0) { cp[strcspn(cp, "\r\n")] = '\0'; if (commentp) { *commentp = strdup(*cp ? cp : filename); if (*commentp == NULL) r = SSH_ERR_ALLOC_FAIL; } fclose(f); return r; } } } fclose(f); return SSH_ERR_INVALID_FORMAT; } /* load public key from ssh v1 private or any pubkey file */ int sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) { struct sshkey *pub = NULL; char file[PATH_MAX]; int r, fd; if (keyp != NULL) *keyp = NULL; if (commentp != NULL) *commentp = NULL; /* XXX should load file once and attempt to parse each format */ if ((fd = open(filename, O_RDONLY)) < 0) goto skip; #ifdef WITH_SSH1 /* try rsa1 private key */ r = sshkey_load_public_rsa1(fd, keyp, commentp); close(fd); switch (r) { case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: case SSH_ERR_INVALID_ARGUMENT: case SSH_ERR_SYSTEM_ERROR: case 0: return r; } #else /* WITH_SSH1 */ close(fd); #endif /* WITH_SSH1 */ /* try ssh2 public key */ if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { if (keyp != NULL) *keyp = pub; return 0; } sshkey_free(pub); #ifdef WITH_SSH1 /* try rsa1 public key */ if ((pub = sshkey_new(KEY_RSA1)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { if (keyp != NULL) *keyp = pub; return 0; } sshkey_free(pub); #endif /* WITH_SSH1 */ skip: /* try .pub suffix */ if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) return SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */ if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && (strlcat(file, ".pub", sizeof file) < sizeof(file)) && (r = sshkey_try_load_public(pub, file, commentp)) == 0) { if (keyp != NULL) *keyp = pub; return 0; } sshkey_free(pub); return r; } /* Load the certificate associated with the named private key */ int sshkey_load_cert(const char *filename, struct sshkey **keyp) { struct sshkey *pub = NULL; char *file = NULL; int r = SSH_ERR_INTERNAL_ERROR; *keyp = NULL; if (asprintf(&file, "%s-cert.pub", filename) == -1) return SSH_ERR_ALLOC_FAIL; if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { goto out; } if ((r = sshkey_try_load_public(pub, file, NULL)) != 0) goto out; *keyp = pub; pub = NULL; r = 0; out: free(file); sshkey_free(pub); return r; } /* Load private key and certificate */ int sshkey_load_private_cert(int type, const char *filename, const char *passphrase, struct sshkey **keyp, int *perm_ok) { struct sshkey *key = NULL, *cert = NULL; int r; *keyp = NULL; switch (type) { #ifdef WITH_OPENSSL case KEY_RSA: case KEY_DSA: case KEY_ECDSA: #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_UNSPEC: break; default: return SSH_ERR_KEY_TYPE_UNKNOWN; } if ((r = sshkey_load_private_type(type, filename, passphrase, &key, NULL, perm_ok)) != 0 || (r = sshkey_load_cert(filename, &cert)) != 0) goto out; /* Make sure the private key matches the certificate */ if (sshkey_equal_public(key, cert) == 0) { r = SSH_ERR_KEY_CERT_MISMATCH; goto out; } if ((r = sshkey_to_certified(key)) != 0 || (r = sshkey_cert_copy(cert, key)) != 0) goto out; r = 0; *keyp = key; key = NULL; out: sshkey_free(key); sshkey_free(cert); return r; } /* * Returns success if the specified "key" is listed in the file "filename", * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. * If "strict_type" is set then the key type must match exactly, * otherwise a comparison that ignores certficiate data is performed. * If "check_ca" is set and "key" is a certificate, then its CA key is * also checked and sshkey_in_file() will return success if either is found. */ int sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, int check_ca) { FILE *f; char line[SSH_MAX_PUBKEY_BYTES]; char *cp; u_long linenum = 0; int r = 0; struct sshkey *pub = NULL; int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = strict_type ? sshkey_equal : sshkey_equal_public; if ((f = fopen(filename, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; while (read_keyfile_line(f, filename, line, sizeof(line), &linenum) != -1) { cp = line; /* Skip leading whitespace. */ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) ; /* Skip comments and empty lines */ switch (*cp) { case '#': case '\n': case '\0': continue; } if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_read(pub, &cp)) != 0) goto out; if (sshkey_compare(key, pub) || (check_ca && sshkey_is_cert(key) && sshkey_compare(key->cert->signature_key, pub))) { r = 0; goto out; } sshkey_free(pub); pub = NULL; } r = SSH_ERR_KEY_NOT_FOUND; out: sshkey_free(pub); fclose(f); return r; } /* * Checks whether the specified key is revoked, returning 0 if not, * SSH_ERR_KEY_REVOKED if it is or another error code if something * unexpected happened. * This will check both the key and, if it is a certificate, its CA key too. * "revoked_keys_file" may be a KRL or a one-per-line list of public keys. */ int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file) { int r; r = ssh_krl_file_contains_key(revoked_keys_file, key); /* If this was not a KRL to begin with then continue below */ if (r != SSH_ERR_KRL_BAD_MAGIC) return r; /* * If the file is not a KRL or we can't handle KRLs then attempt to * parse the file as a flat list of keys. */ switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) { case 0: /* Key found => revoked */ return SSH_ERR_KEY_REVOKED; case SSH_ERR_KEY_NOT_FOUND: /* Key not found => not revoked */ return 0; default: /* Some other error occurred */ return r; } } openssh-7.2p2/authfile.h010064400017500001750000000045301267006270000134260ustar00djmdjm/* $OpenBSD: authfile.h,v 1.21 2015/01/08 10:14:08 djm Exp $ */ /* * Copyright (c) 2000, 2013 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 AUTHFILE_H #define AUTHFILE_H struct sshbuf; struct sshkey; /* XXX document these */ /* XXX some of these could probably be merged/retired */ int sshkey_save_private(struct sshkey *, const char *, const char *, const char *, int, const char *, int); int sshkey_load_file(int, struct sshbuf *); int sshkey_load_cert(const char *, struct sshkey **); int sshkey_load_public(const char *, struct sshkey **, char **); int sshkey_load_private(const char *, const char *, struct sshkey **, char **); int sshkey_load_private_cert(int, const char *, const char *, struct sshkey **, int *); int sshkey_load_private_type(int, const char *, const char *, struct sshkey **, char **, int *); int sshkey_load_private_type_fd(int fd, int type, const char *passphrase, struct sshkey **keyp, char **commentp); int sshkey_perm_ok(int, const char *); int sshkey_in_file(struct sshkey *, const char *, int, int); int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file); #endif openssh-7.2p2/bitmap.c010064400017500001750000000106411267006270000130740ustar00djmdjm/* * Copyright (c) 2015 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #include #include #include "bitmap.h" #define BITMAP_WTYPE u_int #define BITMAP_MAX (1<<24) #define BITMAP_BYTES (sizeof(BITMAP_WTYPE)) #define BITMAP_BITS (sizeof(BITMAP_WTYPE) * 8) #define BITMAP_WMASK ((BITMAP_WTYPE)BITMAP_BITS - 1) struct bitmap { BITMAP_WTYPE *d; size_t len; /* number of words allocated */ size_t top; /* index of top word allocated */ }; struct bitmap * bitmap_new(void) { struct bitmap *ret; if ((ret = calloc(1, sizeof(*ret))) == NULL) return NULL; if ((ret->d = calloc(1, BITMAP_BYTES)) == NULL) { free(ret); return NULL; } ret->len = 1; ret->top = 0; return ret; } void bitmap_free(struct bitmap *b) { if (b != NULL && b->d != NULL) { explicit_bzero(b->d, b->len); free(b->d); } free(b); } void bitmap_zero(struct bitmap *b) { memset(b->d, 0, b->len * BITMAP_BYTES); b->top = 0; } int bitmap_test_bit(struct bitmap *b, u_int n) { if (b->top >= b->len) return 0; /* invalid */ if (b->len == 0 || (n / BITMAP_BITS) > b->top) return 0; return (b->d[n / BITMAP_BITS] >> (n & BITMAP_WMASK)) & 1; } static int reserve(struct bitmap *b, u_int n) { BITMAP_WTYPE *tmp; size_t nlen; if (b->top >= b->len || n > BITMAP_MAX) return -1; /* invalid */ nlen = (n / BITMAP_BITS) + 1; if (b->len < nlen) { if ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL) return -1; b->d = tmp; memset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES); b->len = nlen; } return 0; } int bitmap_set_bit(struct bitmap *b, u_int n) { int r; size_t offset; if ((r = reserve(b, n)) != 0) return r; offset = n / BITMAP_BITS; if (offset > b->top) b->top = offset; b->d[offset] |= (BITMAP_WTYPE)1 << (n & BITMAP_WMASK); return 0; } /* Resets b->top to point to the most significant bit set in b->d */ static void retop(struct bitmap *b) { if (b->top >= b->len) return; while (b->top > 0 && b->d[b->top] == 0) b->top--; } void bitmap_clear_bit(struct bitmap *b, u_int n) { size_t offset; if (b->top >= b->len || n > BITMAP_MAX) return; /* invalid */ offset = n / BITMAP_BITS; if (offset > b->top) return; b->d[offset] &= ~((BITMAP_WTYPE)1 << (n & BITMAP_WMASK)); /* The top may have changed as a result of the clear */ retop(b); } size_t bitmap_nbits(struct bitmap *b) { size_t bits; BITMAP_WTYPE w; retop(b); if (b->top >= b->len) return 0; /* invalid */ if (b->len == 0 || (b->top == 0 && b->d[0] == 0)) return 0; /* Find MSB set */ w = b->d[b->top]; bits = (b->top + 1) * BITMAP_BITS; while (!(w & ((BITMAP_WTYPE)1 << (BITMAP_BITS - 1)))) { w <<= 1; bits--; } return bits; } size_t bitmap_nbytes(struct bitmap *b) { return (bitmap_nbits(b) + 7) / 8; } int bitmap_to_string(struct bitmap *b, void *p, size_t l) { u_char *s = (u_char *)p; size_t i, j, k, need = bitmap_nbytes(b); if (l < need || b->top >= b->len) return -1; if (l > need) l = need; /* Put the bytes from LSB backwards */ for (i = k = 0; i < b->top + 1; i++) { for (j = 0; j < BITMAP_BYTES; j++) { if (k >= l) break; s[need - 1 - k++] = (b->d[i] >> (j * 8)) & 0xff; } } return 0; } int bitmap_from_string(struct bitmap *b, const void *p, size_t l) { int r; size_t i, offset, shift; u_char *s = (u_char *)p; if (l > BITMAP_MAX / 8) return -1; if ((r = reserve(b, l * 8)) != 0) return r; bitmap_zero(b); if (l == 0) return 0; b->top = offset = ((l + (BITMAP_BYTES - 1)) / BITMAP_BYTES) - 1; shift = ((l + (BITMAP_BYTES - 1)) % BITMAP_BYTES) * 8; for (i = 0; i < l; i++) { b->d[offset] |= (BITMAP_WTYPE)s[i] << shift; if (shift == 0) { offset--; shift = BITMAP_BITS - 8; } else shift -= 8; } retop(b); return 0; } openssh-7.2p2/bitmap.h010064400017500001750000000035341267006270000131040ustar00djmdjm/* * Copyright (c) 2015 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _BITMAP_H #define _BITMAP_H #include /* Simple bit vector routines */ struct bitmap; /* Allocate a new bitmap. Returns NULL on allocation failure. */ struct bitmap *bitmap_new(void); /* Free a bitmap */ void bitmap_free(struct bitmap *b); /* Zero an existing bitmap */ void bitmap_zero(struct bitmap *b); /* Test whether a bit is set in a bitmap. */ int bitmap_test_bit(struct bitmap *b, u_int n); /* Set a bit in a bitmap. Returns 0 on success or -1 on error */ int bitmap_set_bit(struct bitmap *b, u_int n); /* Clear a bit in a bitmap */ void bitmap_clear_bit(struct bitmap *b, u_int n); /* Return the number of bits in a bitmap (i.e. the position of the MSB) */ size_t bitmap_nbits(struct bitmap *b); /* Return the number of bytes needed to represent a bitmap */ size_t bitmap_nbytes(struct bitmap *b); /* Convert a bitmap to a big endian byte string */ int bitmap_to_string(struct bitmap *b, void *p, size_t l); /* Convert a big endian byte string to a bitmap */ int bitmap_from_string(struct bitmap *b, const void *p, size_t l); #endif /* _BITMAP_H */ openssh-7.2p2/blocks.c010064400017500001750000000147641267006270000131070ustar00djmdjm/* $OpenBSD: blocks.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Author: Daniel J. Bernstein * Copied from nacl-20110221/crypto_hashblocks/sha512/ref/blocks.c */ #include "includes.h" #include "crypto_api.h" typedef unsigned long long uint64; static uint64 load_bigendian(const unsigned char *x) { return (uint64) (x[7]) \ | (((uint64) (x[6])) << 8) \ | (((uint64) (x[5])) << 16) \ | (((uint64) (x[4])) << 24) \ | (((uint64) (x[3])) << 32) \ | (((uint64) (x[2])) << 40) \ | (((uint64) (x[1])) << 48) \ | (((uint64) (x[0])) << 56) ; } static void store_bigendian(unsigned char *x,uint64 u) { x[7] = u; u >>= 8; x[6] = u; u >>= 8; x[5] = u; u >>= 8; x[4] = u; u >>= 8; x[3] = u; u >>= 8; x[2] = u; u >>= 8; x[1] = u; u >>= 8; x[0] = u; } #define SHR(x,c) ((x) >> (c)) #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) #define Ch(x,y,z) ((x & y) ^ (~x & z)) #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) #define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; #define EXPAND \ M(w0 ,w14,w9 ,w1 ) \ M(w1 ,w15,w10,w2 ) \ M(w2 ,w0 ,w11,w3 ) \ M(w3 ,w1 ,w12,w4 ) \ M(w4 ,w2 ,w13,w5 ) \ M(w5 ,w3 ,w14,w6 ) \ M(w6 ,w4 ,w15,w7 ) \ M(w7 ,w5 ,w0 ,w8 ) \ M(w8 ,w6 ,w1 ,w9 ) \ M(w9 ,w7 ,w2 ,w10) \ M(w10,w8 ,w3 ,w11) \ M(w11,w9 ,w4 ,w12) \ M(w12,w10,w5 ,w13) \ M(w13,w11,w6 ,w14) \ M(w14,w12,w7 ,w15) \ M(w15,w13,w8 ,w0 ) #define F(w,k) \ T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ T2 = Sigma0(a) + Maj(a,b,c); \ h = g; \ g = f; \ f = e; \ e = d + T1; \ d = c; \ c = b; \ b = a; \ a = T1 + T2; int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) { uint64 state[8]; uint64 a; uint64 b; uint64 c; uint64 d; uint64 e; uint64 f; uint64 g; uint64 h; uint64 T1; uint64 T2; a = load_bigendian(statebytes + 0); state[0] = a; b = load_bigendian(statebytes + 8); state[1] = b; c = load_bigendian(statebytes + 16); state[2] = c; d = load_bigendian(statebytes + 24); state[3] = d; e = load_bigendian(statebytes + 32); state[4] = e; f = load_bigendian(statebytes + 40); state[5] = f; g = load_bigendian(statebytes + 48); state[6] = g; h = load_bigendian(statebytes + 56); state[7] = h; while (inlen >= 128) { uint64 w0 = load_bigendian(in + 0); uint64 w1 = load_bigendian(in + 8); uint64 w2 = load_bigendian(in + 16); uint64 w3 = load_bigendian(in + 24); uint64 w4 = load_bigendian(in + 32); uint64 w5 = load_bigendian(in + 40); uint64 w6 = load_bigendian(in + 48); uint64 w7 = load_bigendian(in + 56); uint64 w8 = load_bigendian(in + 64); uint64 w9 = load_bigendian(in + 72); uint64 w10 = load_bigendian(in + 80); uint64 w11 = load_bigendian(in + 88); uint64 w12 = load_bigendian(in + 96); uint64 w13 = load_bigendian(in + 104); uint64 w14 = load_bigendian(in + 112); uint64 w15 = load_bigendian(in + 120); F(w0 ,0x428a2f98d728ae22ULL) F(w1 ,0x7137449123ef65cdULL) F(w2 ,0xb5c0fbcfec4d3b2fULL) F(w3 ,0xe9b5dba58189dbbcULL) F(w4 ,0x3956c25bf348b538ULL) F(w5 ,0x59f111f1b605d019ULL) F(w6 ,0x923f82a4af194f9bULL) F(w7 ,0xab1c5ed5da6d8118ULL) F(w8 ,0xd807aa98a3030242ULL) F(w9 ,0x12835b0145706fbeULL) F(w10,0x243185be4ee4b28cULL) F(w11,0x550c7dc3d5ffb4e2ULL) F(w12,0x72be5d74f27b896fULL) F(w13,0x80deb1fe3b1696b1ULL) F(w14,0x9bdc06a725c71235ULL) F(w15,0xc19bf174cf692694ULL) EXPAND F(w0 ,0xe49b69c19ef14ad2ULL) F(w1 ,0xefbe4786384f25e3ULL) F(w2 ,0x0fc19dc68b8cd5b5ULL) F(w3 ,0x240ca1cc77ac9c65ULL) F(w4 ,0x2de92c6f592b0275ULL) F(w5 ,0x4a7484aa6ea6e483ULL) F(w6 ,0x5cb0a9dcbd41fbd4ULL) F(w7 ,0x76f988da831153b5ULL) F(w8 ,0x983e5152ee66dfabULL) F(w9 ,0xa831c66d2db43210ULL) F(w10,0xb00327c898fb213fULL) F(w11,0xbf597fc7beef0ee4ULL) F(w12,0xc6e00bf33da88fc2ULL) F(w13,0xd5a79147930aa725ULL) F(w14,0x06ca6351e003826fULL) F(w15,0x142929670a0e6e70ULL) EXPAND F(w0 ,0x27b70a8546d22ffcULL) F(w1 ,0x2e1b21385c26c926ULL) F(w2 ,0x4d2c6dfc5ac42aedULL) F(w3 ,0x53380d139d95b3dfULL) F(w4 ,0x650a73548baf63deULL) F(w5 ,0x766a0abb3c77b2a8ULL) F(w6 ,0x81c2c92e47edaee6ULL) F(w7 ,0x92722c851482353bULL) F(w8 ,0xa2bfe8a14cf10364ULL) F(w9 ,0xa81a664bbc423001ULL) F(w10,0xc24b8b70d0f89791ULL) F(w11,0xc76c51a30654be30ULL) F(w12,0xd192e819d6ef5218ULL) F(w13,0xd69906245565a910ULL) F(w14,0xf40e35855771202aULL) F(w15,0x106aa07032bbd1b8ULL) EXPAND F(w0 ,0x19a4c116b8d2d0c8ULL) F(w1 ,0x1e376c085141ab53ULL) F(w2 ,0x2748774cdf8eeb99ULL) F(w3 ,0x34b0bcb5e19b48a8ULL) F(w4 ,0x391c0cb3c5c95a63ULL) F(w5 ,0x4ed8aa4ae3418acbULL) F(w6 ,0x5b9cca4f7763e373ULL) F(w7 ,0x682e6ff3d6b2b8a3ULL) F(w8 ,0x748f82ee5defb2fcULL) F(w9 ,0x78a5636f43172f60ULL) F(w10,0x84c87814a1f0ab72ULL) F(w11,0x8cc702081a6439ecULL) F(w12,0x90befffa23631e28ULL) F(w13,0xa4506cebde82bde9ULL) F(w14,0xbef9a3f7b2c67915ULL) F(w15,0xc67178f2e372532bULL) EXPAND F(w0 ,0xca273eceea26619cULL) F(w1 ,0xd186b8c721c0c207ULL) F(w2 ,0xeada7dd6cde0eb1eULL) F(w3 ,0xf57d4f7fee6ed178ULL) F(w4 ,0x06f067aa72176fbaULL) F(w5 ,0x0a637dc5a2c898a6ULL) F(w6 ,0x113f9804bef90daeULL) F(w7 ,0x1b710b35131c471bULL) F(w8 ,0x28db77f523047d84ULL) F(w9 ,0x32caab7b40c72493ULL) F(w10,0x3c9ebe0a15c9bebcULL) F(w11,0x431d67c49c100d4cULL) F(w12,0x4cc5d4becb3e42b6ULL) F(w13,0x597f299cfc657e2aULL) F(w14,0x5fcb6fab3ad6faecULL) F(w15,0x6c44198c4a475817ULL) a += state[0]; b += state[1]; c += state[2]; d += state[3]; e += state[4]; f += state[5]; g += state[6]; h += state[7]; state[0] = a; state[1] = b; state[2] = c; state[3] = d; state[4] = e; state[5] = f; state[6] = g; state[7] = h; in += 128; inlen -= 128; } store_bigendian(statebytes + 0,state[0]); store_bigendian(statebytes + 8,state[1]); store_bigendian(statebytes + 16,state[2]); store_bigendian(statebytes + 24,state[3]); store_bigendian(statebytes + 32,state[4]); store_bigendian(statebytes + 40,state[5]); store_bigendian(statebytes + 48,state[6]); store_bigendian(statebytes + 56,state[7]); return inlen; } openssh-7.2p2/bufaux.c010064400017500001750000000121551267006270000131140ustar00djmdjm/* $OpenBSD: bufaux.c,v 1.60 2014/04/30 05:29:56 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ #include "includes.h" #include #include "buffer.h" #include "log.h" #include "ssherr.h" int buffer_get_short_ret(u_short *v, Buffer *buffer) { int ret; if ((ret = sshbuf_get_u16(buffer, v)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } u_short buffer_get_short(Buffer *buffer) { u_short ret; if (buffer_get_short_ret(&ret, buffer) == -1) fatal("%s: buffer error", __func__); return (ret); } int buffer_get_int_ret(u_int *v, Buffer *buffer) { int ret; if ((ret = sshbuf_get_u32(buffer, v)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } u_int buffer_get_int(Buffer *buffer) { u_int ret; if (buffer_get_int_ret(&ret, buffer) == -1) fatal("%s: buffer error", __func__); return (ret); } int buffer_get_int64_ret(u_int64_t *v, Buffer *buffer) { int ret; if ((ret = sshbuf_get_u64(buffer, v)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } u_int64_t buffer_get_int64(Buffer *buffer) { u_int64_t ret; if (buffer_get_int64_ret(&ret, buffer) == -1) fatal("%s: buffer error", __func__); return (ret); } void buffer_put_short(Buffer *buffer, u_short value) { int ret; if ((ret = sshbuf_put_u16(buffer, value)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_put_int(Buffer *buffer, u_int value) { int ret; if ((ret = sshbuf_put_u32(buffer, value)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_put_int64(Buffer *buffer, u_int64_t value) { int ret; if ((ret = sshbuf_put_u64(buffer, value)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void * buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) { size_t len; int ret; u_char *value; if ((ret = sshbuf_get_string(buffer, &value, &len)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return NULL; } if (length_ptr != NULL) *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ 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("%s: buffer error", __func__); return (ret); } char * buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr) { size_t len; int ret; char *value; if ((ret = sshbuf_get_cstring(buffer, &value, &len)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return NULL; } if (length_ptr != NULL) *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ return value; } char * buffer_get_cstring(Buffer *buffer, u_int *length_ptr) { char *ret; if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL) fatal("%s: buffer error", __func__); return ret; } const void * buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) { size_t len; int ret; const u_char *value; if ((ret = sshbuf_get_string_direct(buffer, &value, &len)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return NULL; } if (length_ptr != NULL) *length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */ return value; } const void * buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) { const void *ret; if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) fatal("%s: buffer error", __func__); return (ret); } void buffer_put_string(Buffer *buffer, const void *buf, u_int len) { int ret; if ((ret = sshbuf_put_string(buffer, buf, len)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_put_cstring(Buffer *buffer, const char *s) { int ret; if ((ret = sshbuf_put_cstring(buffer, s)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } int buffer_get_char_ret(char *v, Buffer *buffer) { int ret; if ((ret = sshbuf_get_u8(buffer, (u_char *)v)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } int buffer_get_char(Buffer *buffer) { char ch; if (buffer_get_char_ret(&ch, buffer) == -1) fatal("%s: buffer error", __func__); return (u_char) ch; } void buffer_put_char(Buffer *buffer, int value) { int ret; if ((ret = sshbuf_put_u8(buffer, value)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) { int ret; if ((ret = sshbuf_put_bignum2_bytes(buffer, s, l)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } openssh-7.2p2/bufbn.c010064400017500001750000000047331267006270000127210ustar00djmdjm/* $OpenBSD: bufbn.c,v 1.12 2014/04/30 05:29:56 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ #include "includes.h" #ifdef WITH_OPENSSL #include #include "buffer.h" #include "log.h" #include "ssherr.h" #ifdef WITH_SSH1 int buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) { int ret; if ((ret = sshbuf_put_bignum1(buffer, value)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_put_bignum(Buffer *buffer, const BIGNUM *value) { if (buffer_put_bignum_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } int buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) { int ret; if ((ret = sshbuf_get_bignum1(buffer, value)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_get_bignum(Buffer *buffer, BIGNUM *value) { if (buffer_get_bignum_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } #endif /* WITH_SSH1 */ int buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) { int ret; if ((ret = sshbuf_put_bignum2(buffer, value)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_put_bignum2(Buffer *buffer, const BIGNUM *value) { if (buffer_put_bignum2_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } int buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value) { int ret; if ((ret = sshbuf_get_bignum2(buffer, value)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_get_bignum2(Buffer *buffer, BIGNUM *value) { if (buffer_get_bignum2_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } #endif /* WITH_OPENSSL */ openssh-7.2p2/bufec.c010064400017500001750000000036011267006270000127020ustar00djmdjm/* $OpenBSD: bufec.c,v 1.4 2014/04/30 05:29:56 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ #include "includes.h" #include #include "buffer.h" #include "log.h" #include "ssherr.h" #ifdef OPENSSL_HAS_ECC int buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, const EC_POINT *point) { int ret; if ((ret = sshbuf_put_ec(buffer, point, curve)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_put_ecpoint(Buffer *buffer, const EC_GROUP *curve, const EC_POINT *point) { if (buffer_put_ecpoint_ret(buffer, curve, point) == -1) fatal("%s: buffer error", __func__); } int buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, EC_POINT *point) { int ret; if ((ret = sshbuf_get_ec(buffer, point, curve)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_get_ecpoint(Buffer *buffer, const EC_GROUP *curve, EC_POINT *point) { if (buffer_get_ecpoint_ret(buffer, curve, point) == -1) fatal("%s: buffer error", __func__); } #endif /* OPENSSL_HAS_ECC */ openssh-7.2p2/buffer.c010064400017500001750000000051711267006270000130730ustar00djmdjm/* $OpenBSD: buffer.c,v 1.36 2014/04/30 05:29:56 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ #include "includes.h" #include #include "buffer.h" #include "log.h" #include "ssherr.h" void buffer_append(Buffer *buffer, const void *data, u_int len) { int ret; if ((ret = sshbuf_put(buffer, data, len)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); } void * buffer_append_space(Buffer *buffer, u_int len) { int ret; u_char *p; if ((ret = sshbuf_reserve(buffer, len, &p)) != 0) fatal("%s: %s", __func__, ssh_err(ret)); return p; } int buffer_check_alloc(Buffer *buffer, u_int len) { int ret = sshbuf_check_reserve(buffer, len); if (ret == 0) return 1; if (ret == SSH_ERR_NO_BUFFER_SPACE) return 0; fatal("%s: %s", __func__, ssh_err(ret)); } int buffer_get_ret(Buffer *buffer, void *buf, u_int len) { int ret; if ((ret = sshbuf_get(buffer, buf, len)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; } void buffer_get(Buffer *buffer, void *buf, u_int len) { if (buffer_get_ret(buffer, buf, len) == -1) fatal("%s: buffer error", __func__); } int buffer_consume_ret(Buffer *buffer, u_int bytes) { int ret = sshbuf_consume(buffer, bytes); if (ret == 0) return 0; if (ret == SSH_ERR_MESSAGE_INCOMPLETE) return -1; fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_consume(Buffer *buffer, u_int bytes) { if (buffer_consume_ret(buffer, bytes) == -1) fatal("%s: buffer error", __func__); } int buffer_consume_end_ret(Buffer *buffer, u_int bytes) { int ret = sshbuf_consume_end(buffer, bytes); if (ret == 0) return 0; if (ret == SSH_ERR_MESSAGE_INCOMPLETE) return -1; fatal("%s: %s", __func__, ssh_err(ret)); } void buffer_consume_end(Buffer *buffer, u_int bytes) { if (buffer_consume_end_ret(buffer, bytes) == -1) fatal("%s: buffer error", __func__); } openssh-7.2p2/buffer.h010064400017500001750000000070011267006270000130720ustar00djmdjm/* $OpenBSD: buffer.h,v 1.25 2014/04/30 05:29:56 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */ #ifndef BUFFER_H #define BUFFER_H #include "sshbuf.h" typedef struct sshbuf Buffer; #define buffer_init(b) sshbuf_init(b) #define buffer_clear(b) sshbuf_reset(b) #define buffer_free(b) sshbuf_free(b) #define buffer_dump(b) sshbuf_dump(b, stderr) /* XXX cast is safe: sshbuf never stores more than len 2^31 */ #define buffer_len(b) ((u_int) sshbuf_len(b)) #define buffer_ptr(b) sshbuf_mutable_ptr(b) 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); int buffer_get_ret(Buffer *, void *, u_int); int buffer_consume_ret(Buffer *, u_int); int buffer_consume_end_ret(Buffer *, u_int); #include #include 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 *); void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); 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 *); const void *buffer_get_string_ptr(Buffer *, u_int *); void buffer_put_string(Buffer *, const void *, u_int); char *buffer_get_cstring(Buffer *, u_int *); void buffer_put_cstring(Buffer *, const char *); #define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL); 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 *); char *buffer_get_cstring_ret(Buffer *, u_int *); const void *buffer_get_string_ptr_ret(Buffer *, u_int *); int buffer_get_char_ret(char *, Buffer *); #ifdef OPENSSL_HAS_ECC #include int buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *); void buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *); int buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *); void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *); #endif #endif /* BUFFER_H */ openssh-7.2p2/buildpkg.sh.in010064400017500001750000000432151267006270000142210ustar00djmdjm#!/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/${SYSVINIT_NAME}:default SMF_METHOD_DIR=/lib/svc/method/site SMF_MANIFEST_DIR=/var/svc/manifest/site 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}${SMF_METHOD_DIR} mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR} cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} chmod 744 $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} cat ${OPENSSH_MANIFEST} | \ sed -e "s|__SYSVINIT_NAME__|${SYSVINIT_NAME}|" \ -e "s|__SMF_METHOD_DIR__|${SMF_METHOD_DIR}|" \ > $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml chmod 644 $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml 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 # 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 # 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, The manifest disables sshd by default. svccfg import ${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml 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 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 -H $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 <> 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 <> 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 openssh-7.2p2/canohost.c010064400017500001750000000263631267006270000134460ustar00djmdjm/* $OpenBSD: canohost.c,v 1.72 2015/03/01 15:44:40 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "packet.h" #include "log.h" #include "canohost.h" #include "misc.h" static void check_ip_options(int, char *); static char *canonical_host_ip = NULL; static int cached_port = -1; /* * Return the canonical name of the host at the other end of the socket. The * caller should free the returned string. */ static char * get_remote_hostname(int sock, int use_dns) { struct sockaddr_storage from; 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, NULL, &hints, &ai) == 0) { logit("Nasty PTR record \"%s\" is set up for %s, ignoring", name, ntop); freeaddrinfo(ai); return xstrdup(ntop); } /* Names are stores in lowercase. */ lowercase(name); /* * 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, 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(a4, 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); } switch (addr.ss_family) { case AF_INET: case AF_INET6: /* 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, ssh_gai_strerror(r)); return NULL; } return xstrdup(ntop); case AF_UNIX: /* Get the Unix domain socket path. */ return xstrdup(((struct sockaddr_un *)&addr)->sun_path); default: /* We can't look up remote Unix domain sockets. */ return NULL; } } 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 fd) { char *host, myname[NI_MAXHOST]; /* Assume we were passed a socket */ if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL) return host; /* Handle the case where we were passed a pipe */ if (gethostname(myname, sizeof(myname)) == -1) { verbose("get_local_name: gethostname: %s", strerror(errno)); } else { host = xstrdup(myname); } return host; } void clear_cached_addr(void) { free(canonical_host_ip); canonical_host_ip = NULL; cached_port = -1; } /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. */ const char * get_remote_ipaddr(void) { /* 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. */ 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); /* Non-inet sockets don't have a port number. */ if (from.ss_family != AF_INET && from.ss_family != AF_INET6) return 0; /* 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", ssh_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) { /* Cache to avoid getpeername() on a dead connection */ if (cached_port == -1) cached_port = get_port(0); return cached_port; } int get_local_port(void) { return get_port(1); } openssh-7.2p2/canohost.h010064400017500001750000000017501267006270000134440ustar00djmdjm/* $OpenBSD: canohost.h,v 1.11 2009/05/27 06:31:25 andreas Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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); int get_sock_port(int, int); void clear_cached_addr(void); void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); openssh-7.2p2/chacha.c010064400017500001750000000124431267006270000130310ustar00djmdjm/* chacha-merged.c version 20080118 D. J. Bernstein Public domain. */ #include "includes.h" #include "chacha.h" /* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */ typedef unsigned char u8; typedef unsigned int u32; typedef struct chacha_ctx chacha_ctx; #define U8C(v) (v##U) #define U32C(v) (v##U) #define U8V(v) ((u8)(v) & U8C(0xFF)) #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) #define ROTL32(v, n) \ (U32V((v) << (n)) | ((v) >> (32 - (n)))) #define U8TO32_LITTLE(p) \ (((u32)((p)[0]) ) | \ ((u32)((p)[1]) << 8) | \ ((u32)((p)[2]) << 16) | \ ((u32)((p)[3]) << 24)) #define U32TO8_LITTLE(p, v) \ do { \ (p)[0] = U8V((v) ); \ (p)[1] = U8V((v) >> 8); \ (p)[2] = U8V((v) >> 16); \ (p)[3] = U8V((v) >> 24); \ } while (0) #define ROTATE(v,c) (ROTL32(v,c)) #define XOR(v,w) ((v) ^ (w)) #define PLUS(v,w) (U32V((v) + (w))) #define PLUSONE(v) (PLUS((v),1)) #define QUARTERROUND(a,b,c,d) \ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; void chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) { const char *constants; x->input[4] = U8TO32_LITTLE(k + 0); x->input[5] = U8TO32_LITTLE(k + 4); x->input[6] = U8TO32_LITTLE(k + 8); x->input[7] = U8TO32_LITTLE(k + 12); if (kbits == 256) { /* recommended */ k += 16; constants = sigma; } else { /* kbits == 128 */ constants = tau; } x->input[8] = U8TO32_LITTLE(k + 0); x->input[9] = U8TO32_LITTLE(k + 4); x->input[10] = U8TO32_LITTLE(k + 8); x->input[11] = U8TO32_LITTLE(k + 12); x->input[0] = U8TO32_LITTLE(constants + 0); x->input[1] = U8TO32_LITTLE(constants + 4); x->input[2] = U8TO32_LITTLE(constants + 8); x->input[3] = U8TO32_LITTLE(constants + 12); } void chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) { x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); x->input[14] = U8TO32_LITTLE(iv + 0); x->input[15] = U8TO32_LITTLE(iv + 4); } void chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) { u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; u8 *ctarget = NULL; u8 tmp[64]; u_int i; if (!bytes) return; j0 = x->input[0]; j1 = x->input[1]; j2 = x->input[2]; j3 = x->input[3]; j4 = x->input[4]; j5 = x->input[5]; j6 = x->input[6]; j7 = x->input[7]; j8 = x->input[8]; j9 = x->input[9]; j10 = x->input[10]; j11 = x->input[11]; j12 = x->input[12]; j13 = x->input[13]; j14 = x->input[14]; j15 = x->input[15]; for (;;) { if (bytes < 64) { for (i = 0;i < bytes;++i) tmp[i] = m[i]; m = tmp; ctarget = c; c = tmp; } x0 = j0; x1 = j1; x2 = j2; x3 = j3; x4 = j4; x5 = j5; x6 = j6; x7 = j7; x8 = j8; x9 = j9; x10 = j10; x11 = j11; x12 = j12; x13 = j13; x14 = j14; x15 = j15; for (i = 20;i > 0;i -= 2) { QUARTERROUND( x0, x4, x8,x12) QUARTERROUND( x1, x5, x9,x13) QUARTERROUND( x2, x6,x10,x14) QUARTERROUND( x3, x7,x11,x15) QUARTERROUND( x0, x5,x10,x15) QUARTERROUND( x1, x6,x11,x12) QUARTERROUND( x2, x7, x8,x13) QUARTERROUND( x3, x4, x9,x14) } x0 = PLUS(x0,j0); x1 = PLUS(x1,j1); x2 = PLUS(x2,j2); x3 = PLUS(x3,j3); x4 = PLUS(x4,j4); x5 = PLUS(x5,j5); x6 = PLUS(x6,j6); x7 = PLUS(x7,j7); x8 = PLUS(x8,j8); x9 = PLUS(x9,j9); x10 = PLUS(x10,j10); x11 = PLUS(x11,j11); x12 = PLUS(x12,j12); x13 = PLUS(x13,j13); x14 = PLUS(x14,j14); x15 = PLUS(x15,j15); x0 = XOR(x0,U8TO32_LITTLE(m + 0)); x1 = XOR(x1,U8TO32_LITTLE(m + 4)); x2 = XOR(x2,U8TO32_LITTLE(m + 8)); x3 = XOR(x3,U8TO32_LITTLE(m + 12)); x4 = XOR(x4,U8TO32_LITTLE(m + 16)); x5 = XOR(x5,U8TO32_LITTLE(m + 20)); x6 = XOR(x6,U8TO32_LITTLE(m + 24)); x7 = XOR(x7,U8TO32_LITTLE(m + 28)); x8 = XOR(x8,U8TO32_LITTLE(m + 32)); x9 = XOR(x9,U8TO32_LITTLE(m + 36)); x10 = XOR(x10,U8TO32_LITTLE(m + 40)); x11 = XOR(x11,U8TO32_LITTLE(m + 44)); x12 = XOR(x12,U8TO32_LITTLE(m + 48)); x13 = XOR(x13,U8TO32_LITTLE(m + 52)); x14 = XOR(x14,U8TO32_LITTLE(m + 56)); x15 = XOR(x15,U8TO32_LITTLE(m + 60)); j12 = PLUSONE(j12); if (!j12) { j13 = PLUSONE(j13); /* stopping at 2^70 bytes per nonce is user's responsibility */ } U32TO8_LITTLE(c + 0,x0); U32TO8_LITTLE(c + 4,x1); U32TO8_LITTLE(c + 8,x2); U32TO8_LITTLE(c + 12,x3); U32TO8_LITTLE(c + 16,x4); U32TO8_LITTLE(c + 20,x5); U32TO8_LITTLE(c + 24,x6); U32TO8_LITTLE(c + 28,x7); U32TO8_LITTLE(c + 32,x8); U32TO8_LITTLE(c + 36,x9); U32TO8_LITTLE(c + 40,x10); U32TO8_LITTLE(c + 44,x11); U32TO8_LITTLE(c + 48,x12); U32TO8_LITTLE(c + 52,x13); U32TO8_LITTLE(c + 56,x14); U32TO8_LITTLE(c + 60,x15); if (bytes <= 64) { if (bytes < 64) { for (i = 0;i < bytes;++i) ctarget[i] = c[i]; } x->input[12] = j12; x->input[13] = j13; return; } bytes -= 64; c += 64; m += 64; } } openssh-7.2p2/chacha.h010064400017500001750000000017171267006270000130400ustar00djmdjm/* $OpenBSD: chacha.h,v 1.3 2014/05/02 03:27:54 djm Exp $ */ /* chacha-merged.c version 20080118 D. J. Bernstein Public domain. */ #ifndef CHACHA_H #define CHACHA_H #include struct chacha_ctx { u_int input[16]; }; #define CHACHA_MINKEYLEN 16 #define CHACHA_NONCELEN 8 #define CHACHA_CTRLEN 8 #define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) #define CHACHA_BLOCKLEN 64 void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits) __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr) __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN))) __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN))); void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m, u_char *c, u_int bytes) __attribute__((__bounded__(__buffer__, 2, 4))) __attribute__((__bounded__(__buffer__, 3, 4))); #endif /* CHACHA_H */ openssh-7.2p2/channels.c010064400017500001750000003416251267006270000134240ustar00djmdjm/* $OpenBSD: channels.c,v 1.349 2016/02/05 13:28:19 naddy Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * This file contains functions for generic socket connection forwarding. * There is also code for initiating connection forwarding for X11 connections, * arbitrary tcp/ip connections, and the authentication agent connection. * * 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 support added by Markus Friedl. * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 1999 Dug Song. All rights reserved. * Copyright (c) 1999 Theo de Raadt. All rights reserved. * * 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 #include /* MIN MAX */ #include #include #include #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" #include "packet.h" #include "log.h" #include "misc.h" #include "buffer.h" #include "channels.h" #include "compat.h" #include "canohost.h" #include "key.h" #include "authfd.h" #include "pathnames.h" /* -- channel core */ /* * Pointer to an array containing all allocated channels. The array is * dynamically extended as needed. */ static Channel **channels = NULL; /* * Size of the channel array. All slots of the array must always be * initialized (at least the type field); unused slots set to NULL */ static u_int channels_alloc = 0; /* * Maximum file descriptor value used in any of the channels. This is * updated in channel_new. */ static int channel_max_fd = 0; /* -- tcp forwarding */ /* * Data structure for storing which hosts are permitted for forward requests. * The local sides of any remote forwards are stored in this array to prevent * a corrupt remote server from accessing arbitrary TCP/IP ports on our local * network (which might be behind a firewall). */ /* XXX: streamlocal wants a path instead of host:port */ /* Overload host_to_connect; we could just make this match Forward */ /* XXX - can we use listen_host instead of listen_path? */ typedef struct { char *host_to_connect; /* Connect to 'host'. */ int port_to_connect; /* Connect to 'port'. */ char *listen_host; /* Remote side should listen address. */ char *listen_path; /* Remote side should listen path. */ int listen_port; /* Remote side should listen port. */ } ForwardPermission; /* List of all permitted host/port pairs to connect by the user. */ static ForwardPermission *permitted_opens = NULL; /* List of all permitted host/port pairs to connect by the admin. */ static ForwardPermission *permitted_adm_opens = NULL; /* Number of permitted host/port pairs in the array permitted by the user. */ static int num_permitted_opens = 0; /* Number of permitted host/port pair in the array permitted by the admin. */ static int num_adm_permitted_opens = 0; /* special-case port number meaning allow any port */ #define FWD_PERMIT_ANY_PORT 0 /* * If this is true, all opens are permitted. This is the case on the server * on which we have to trust the client anyway, and the user could do * anything after logging in anyway. */ static int all_opens_permitted = 0; /* -- X11 forwarding */ /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 /* Saved X11 local (client) display. */ static char *x11_saved_display = NULL; /* Saved X11 authentication protocol name. */ static char *x11_saved_proto = NULL; /* Saved X11 authentication data. This is the real data. */ static char *x11_saved_data = NULL; static u_int x11_saved_data_len = 0; /* Deadline after which all X11 connections are refused */ static u_int x11_refuse_time; /* * Fake X11 authentication data. This is what the server will be sending us; * we should replace any occurrences of this by the real data. */ static u_char *x11_fake_data = NULL; static u_int x11_fake_data_len; /* -- agent forwarding */ #define NUM_SOCKS 10 /* AF_UNSPEC or AF_INET or AF_INET6 */ static int IPv4or6 = AF_UNSPEC; /* helper */ static void port_open_helper(Channel *c, char *rtype); /* non-blocking connect helpers */ static int connect_next(struct channel_connect *); static void channel_connect_ctx_free(struct channel_connect *); /* -- channel core */ Channel * channel_by_id(int id) { Channel *c; if (id < 0 || (u_int)id >= channels_alloc) { logit("channel_by_id: %d: bad id", id); return NULL; } c = channels[id]; if (c == NULL) { logit("channel_by_id: %d: bad id: channel free", id); return NULL; } return c; } /* * Returns the channel if it is allowed to receive protocol messages. * Private channels, like listening sockets, may not receive messages. */ Channel * channel_lookup(int id) { Channel *c; if ((c = channel_by_id(id)) == NULL) return (NULL); switch (c->type) { case SSH_CHANNEL_X11_OPEN: case SSH_CHANNEL_LARVAL: case SSH_CHANNEL_CONNECTING: case SSH_CHANNEL_DYNAMIC: case SSH_CHANNEL_OPENING: case SSH_CHANNEL_OPEN: case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: case SSH_CHANNEL_ABANDONED: return (c); } logit("Non-public channel %d, type %d.", id, c->type); return (NULL); } /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd */ static void channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage, int nonblock, int is_tty) { /* Update the maximum file descriptor value. */ channel_max_fd = MAX(channel_max_fd, rfd); channel_max_fd = MAX(channel_max_fd, wfd); channel_max_fd = MAX(channel_max_fd, efd); if (rfd != -1) fcntl(rfd, F_SETFD, FD_CLOEXEC); if (wfd != -1 && wfd != rfd) fcntl(wfd, F_SETFD, FD_CLOEXEC); if (efd != -1 && efd != rfd && efd != wfd) fcntl(efd, F_SETFD, FD_CLOEXEC); c->rfd = rfd; c->wfd = wfd; c->sock = (rfd == wfd) ? rfd : -1; c->efd = efd; c->extended_usage = extusage; if ((c->isatty = is_tty) != 0) debug2("channel %d: rfd %d isatty", c->self, c->rfd); #ifdef _AIX /* XXX: Later AIX versions can't push as much data to tty */ c->wfd_isatty = is_tty || isatty(c->wfd); #endif /* enable nonblocking mode */ if (nonblock) { if (rfd != -1) set_nonblock(rfd); if (wfd != -1) set_nonblock(wfd); if (efd != -1) set_nonblock(efd); } } /* * Allocate a new channel object and set its type and socket. This will cause * remote_name to be freed. */ Channel * channel_new(char *ctype, int type, int rfd, int wfd, int efd, u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) { int found; u_int i; Channel *c; /* Do initial allocation if this is the first call. */ if (channels_alloc == 0) { channels_alloc = 10; channels = xcalloc(channels_alloc, sizeof(Channel *)); for (i = 0; i < channels_alloc; i++) channels[i] = NULL; } /* Try to find a free slot where to put the new channel. */ for (found = -1, i = 0; i < channels_alloc; i++) if (channels[i] == NULL) { /* Found a free slot. */ found = (int)i; break; } if (found < 0) { /* There are no free slots. Take last+1 slot and expand the array. */ found = channels_alloc; if (channels_alloc > 10000) fatal("channel_new: internal error: channels_alloc %d " "too big.", channels_alloc); channels = xreallocarray(channels, channels_alloc + 10, sizeof(Channel *)); channels_alloc += 10; debug2("channel: expanding %d", channels_alloc); for (i = found; i < channels_alloc; i++) channels[i] = NULL; } /* Initialize and return new channel. */ c = channels[found] = xcalloc(1, sizeof(Channel)); buffer_init(&c->input); buffer_init(&c->output); buffer_init(&c->extended); c->path = NULL; c->listening_addr = NULL; c->listening_port = 0; c->ostate = CHAN_OUTPUT_OPEN; c->istate = CHAN_INPUT_OPEN; c->flags = 0; channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); c->notbefore = 0; c->self = found; c->type = type; c->ctype = ctype; c->local_window = window; c->local_window_max = window; c->local_consumed = 0; c->local_maxpacket = maxpack; c->remote_id = -1; c->remote_name = xstrdup(remote_name); c->remote_window = 0; c->remote_maxpacket = 0; c->force_drain = 0; c->single_connection = 0; c->detach_user = NULL; c->detach_close = 0; c->open_confirm = NULL; c->open_confirm_ctx = NULL; c->input_filter = NULL; c->output_filter = NULL; c->filter_ctx = NULL; c->filter_cleanup = NULL; c->ctl_chan = -1; c->mux_rcb = NULL; c->mux_ctx = NULL; c->mux_pause = 0; c->delayed = 1; /* prevent call to channel_post handler */ TAILQ_INIT(&c->status_confirms); debug("channel %d: new [%s]", found, remote_name); return c; } static int channel_find_maxfd(void) { u_int i; int max = 0; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c != NULL) { max = MAX(max, c->rfd); max = MAX(max, c->wfd); max = MAX(max, c->efd); } } return max; } int channel_close_fd(int *fdp) { int ret = 0, fd = *fdp; if (fd != -1) { ret = close(fd); *fdp = -1; if (fd == channel_max_fd) channel_max_fd = channel_find_maxfd(); } return ret; } /* Close all channel fd/socket. */ static void channel_close_fds(Channel *c) { channel_close_fd(&c->sock); channel_close_fd(&c->rfd); channel_close_fd(&c->wfd); channel_close_fd(&c->efd); } /* Free the channel and close its fd/socket. */ void channel_free(Channel *c) { char *s; u_int i, n; struct channel_confirm *cc; for (n = 0, i = 0; i < channels_alloc; i++) if (channels[i]) n++; debug("channel %d: free: %s, nchannels %u", c->self, c->remote_name ? c->remote_name : "???", n); s = channel_open_message(); debug3("channel %d: status: %s", c->self, s); free(s); if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); channel_close_fds(c); buffer_free(&c->input); buffer_free(&c->output); buffer_free(&c->extended); free(c->remote_name); c->remote_name = NULL; free(c->path); c->path = NULL; free(c->listening_addr); c->listening_addr = NULL; while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { if (cc->abandon_cb != NULL) cc->abandon_cb(c, cc->ctx); TAILQ_REMOVE(&c->status_confirms, cc, entry); explicit_bzero(cc, sizeof(*cc)); free(cc); } if (c->filter_cleanup != NULL && c->filter_ctx != NULL) c->filter_cleanup(c->self, c->filter_ctx); channels[c->self] = NULL; free(c); } void channel_free_all(void) { u_int i; for (i = 0; i < channels_alloc; i++) if (channels[i] != NULL) channel_free(channels[i]); } /* * Closes the sockets/fds of all channels. This is used to close extra file * descriptors after a fork. */ void channel_close_all(void) { u_int i; for (i = 0; i < channels_alloc; i++) if (channels[i] != NULL) channel_close_fds(channels[i]); } /* * Stop listening to channels. */ void channel_stop_listening(void) { u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c != NULL) { switch (c->type) { case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: channel_close_fd(&c->sock); channel_free(c); break; } } } } /* * Returns true if no channel has too much buffered data, and false if one or * more channel is overfull. */ int channel_not_very_much_buffered_data(void) { u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c != NULL && c->type == SSH_CHANNEL_OPEN) { #if 0 if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { debug2("channel %d: big input buffer %d", c->self, buffer_len(&c->input)); return 0; } #endif if (buffer_len(&c->output) > packet_get_maxsize()) { debug2("channel %d: big output buffer %u > %u", c->self, buffer_len(&c->output), packet_get_maxsize()); return 0; } } } return 1; } /* Returns true if any channel is still open. */ int channel_still_open(void) { u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c == NULL) continue; switch (c->type) { case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_MUX_LISTENER: case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_DYNAMIC: case SSH_CHANNEL_CONNECTING: case SSH_CHANNEL_ZOMBIE: case SSH_CHANNEL_ABANDONED: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: continue; case SSH_CHANNEL_LARVAL: if (!compat20) fatal("cannot happen: SSH_CHANNEL_LARVAL"); continue; case SSH_CHANNEL_OPENING: case SSH_CHANNEL_OPEN: case SSH_CHANNEL_X11_OPEN: case SSH_CHANNEL_MUX_CLIENT: return 1; case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: if (!compat13) fatal("cannot happen: OUT_DRAIN"); return 1; default: fatal("channel_still_open: bad channel type %d", c->type); /* NOTREACHED */ } } return 0; } /* Returns the id of an open channel suitable for keepaliving */ int channel_find_open(void) { u_int i; Channel *c; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c == NULL || c->remote_id < 0) continue; switch (c->type) { case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_DYNAMIC: case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_MUX_LISTENER: case SSH_CHANNEL_MUX_CLIENT: case SSH_CHANNEL_OPENING: case SSH_CHANNEL_CONNECTING: case SSH_CHANNEL_ZOMBIE: case SSH_CHANNEL_ABANDONED: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: continue; case SSH_CHANNEL_LARVAL: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_OPEN: case SSH_CHANNEL_X11_OPEN: return i; case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: if (!compat13) fatal("cannot happen: OUT_DRAIN"); return i; default: fatal("channel_find_open: bad channel type %d", c->type); /* NOTREACHED */ } } return -1; } /* * Returns a message describing the currently open forwarded connections, * suitable for sending to the client. The message contains crlf pairs for * newlines. */ char * channel_open_message(void) { Buffer buffer; Channel *c; char buf[1024], *cp; u_int i; buffer_init(&buffer); snprintf(buf, sizeof buf, "The following connections are open:\r\n"); buffer_append(&buffer, buf, strlen(buf)); for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c == NULL) continue; switch (c->type) { case SSH_CHANNEL_X11_LISTENER: case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_CLOSED: case SSH_CHANNEL_AUTH_SOCKET: case SSH_CHANNEL_ZOMBIE: case SSH_CHANNEL_ABANDONED: case SSH_CHANNEL_MUX_CLIENT: case SSH_CHANNEL_MUX_LISTENER: case SSH_CHANNEL_UNIX_LISTENER: case SSH_CHANNEL_RUNIX_LISTENER: continue; case SSH_CHANNEL_LARVAL: case SSH_CHANNEL_OPENING: case SSH_CHANNEL_CONNECTING: case SSH_CHANNEL_DYNAMIC: case SSH_CHANNEL_OPEN: case SSH_CHANNEL_X11_OPEN: case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n", c->self, c->remote_name, c->type, c->remote_id, c->istate, buffer_len(&c->input), c->ostate, buffer_len(&c->output), c->rfd, c->wfd, c->ctl_chan); buffer_append(&buffer, buf, strlen(buf)); continue; default: fatal("channel_open_message: bad channel type %d", c->type); /* NOTREACHED */ } } buffer_append(&buffer, "\0", 1); cp = xstrdup((char *)buffer_ptr(&buffer)); buffer_free(&buffer); return cp; } void channel_send_open(int id) { Channel *c = channel_lookup(id); if (c == NULL) { logit("channel_send_open: %d: bad id", id); return; } debug2("channel %d: send open", id); packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring(c->ctype); packet_put_int(c->self); packet_put_int(c->local_window); packet_put_int(c->local_maxpacket); packet_send(); } void channel_request_start(int id, char *service, int wantconfirm) { Channel *c = channel_lookup(id); if (c == NULL) { logit("channel_request_start: %d: unknown channel id", id); return; } debug2("channel %d: request %s confirm %d", id, service, wantconfirm); packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring(service); packet_put_char(wantconfirm); } void channel_register_status_confirm(int id, channel_confirm_cb *cb, channel_confirm_abandon_cb *abandon_cb, void *ctx) { struct channel_confirm *cc; Channel *c; if ((c = channel_lookup(id)) == NULL) fatal("channel_register_expect: %d: bad id", id); cc = xcalloc(1, sizeof(*cc)); cc->cb = cb; cc->abandon_cb = abandon_cb; cc->ctx = ctx; TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry); } void channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx) { Channel *c = channel_lookup(id); if (c == NULL) { logit("channel_register_open_confirm: %d: bad id", id); return; } c->open_confirm = fn; c->open_confirm_ctx = ctx; } void channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) { Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_register_cleanup: %d: bad id", id); return; } c->detach_user = fn; c->detach_close = do_close; } void channel_cancel_cleanup(int id) { Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_cancel_cleanup: %d: bad id", id); return; } c->detach_user = NULL; c->detach_close = 0; } void channel_register_filter(int id, channel_infilter_fn *ifn, channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx) { Channel *c = channel_lookup(id); if (c == NULL) { logit("channel_register_filter: %d: bad id", id); return; } c->input_filter = ifn; c->output_filter = ofn; c->filter_ctx = ctx; c->filter_cleanup = cfn; } void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage, int nonblock, int is_tty, u_int window_max) { Channel *c = channel_lookup(id); if (c == NULL || c->type != SSH_CHANNEL_LARVAL) fatal("channel_activate for non-larval channel %d.", id); channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, is_tty); c->type = SSH_CHANNEL_OPEN; c->local_window = c->local_window_max = window_max; packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); packet_put_int(c->local_window); packet_send(); } /* * 'channel_pre*' are called just before select() to add any bits relevant to * channels in the select bitmasks. */ /* * 'channel_post*': perform any appropriate operations for channels which * have events pending. */ typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset); chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; /* ARGSUSED */ static void channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset) { FD_SET(c->sock, readset); } /* ARGSUSED */ static void channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset) { debug3("channel %d: waiting for connection", c->self); FD_SET(c->sock, writeset); } static void channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) { if (buffer_len(&c->input) < packet_get_maxsize()) FD_SET(c->sock, readset); if (buffer_len(&c->output) > 0) FD_SET(c->sock, writeset); } static void channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) { u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); if (c->istate == CHAN_INPUT_OPEN && limit > 0 && buffer_len(&c->input) < limit && buffer_check_alloc(&c->input, CHAN_RBUF)) FD_SET(c->rfd, readset); if (c->ostate == CHAN_OUTPUT_OPEN || c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { if (buffer_len(&c->output) > 0) { FD_SET(c->wfd, writeset); } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) debug2("channel %d: obuf_empty delayed efd %d/(%d)", c->self, c->efd, buffer_len(&c->extended)); else chan_obuf_empty(c); } } /** XXX check close conditions, too */ if (compat20 && c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) { if (c->extended_usage == CHAN_EXTENDED_WRITE && buffer_len(&c->extended) > 0) FD_SET(c->efd, writeset); else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) && (c->extended_usage == CHAN_EXTENDED_READ || c->extended_usage == CHAN_EXTENDED_IGNORE) && buffer_len(&c->extended) < c->remote_window) FD_SET(c->efd, readset); } /* XXX: What about efd? races? */ } /* ARGSUSED */ static void channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset) { if (buffer_len(&c->input) == 0) { packet_start(SSH_MSG_CHANNEL_CLOSE); packet_put_int(c->remote_id); packet_send(); c->type = SSH_CHANNEL_CLOSED; debug2("channel %d: closing after input drain.", c->self); } } /* ARGSUSED */ static void channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset) { if (buffer_len(&c->output) == 0) chan_mark_dead(c); else FD_SET(c->sock, writeset); } /* * This is a special state for X11 authentication spoofing. An opened X11 * connection (when authentication spoofing is being done) remains in this * state until the first packet has been completely read. The authentication * data in that packet is then substituted by the real data if it matches the * fake data, and the channel is put into normal mode. * XXX All this happens at the client side. * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok */ static int x11_open_helper(Buffer *b) { u_char *ucp; u_int proto_len, data_len; /* Is this being called after the refusal deadline? */ if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { verbose("Rejected X11 connection after ForwardX11Timeout " "expired"); return -1; } /* Check if the fixed size part of the packet is in buffer. */ if (buffer_len(b) < 12) return 0; /* Parse the lengths of variable-length fields. */ ucp = buffer_ptr(b); if (ucp[0] == 0x42) { /* Byte order MSB first. */ proto_len = 256 * ucp[6] + ucp[7]; data_len = 256 * ucp[8] + ucp[9]; } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ proto_len = ucp[6] + 256 * ucp[7]; data_len = ucp[8] + 256 * ucp[9]; } else { debug2("Initial X11 packet contains bad byte order byte: 0x%x", ucp[0]); return -1; } /* Check if the whole packet is in buffer. */ if (buffer_len(b) < 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) return 0; /* Check if authentication protocol matches. */ if (proto_len != strlen(x11_saved_proto) || memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { debug2("X11 connection uses different authentication protocol."); return -1; } /* Check if authentication data matches our fake data. */ if (data_len != x11_fake_data_len || timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3), x11_fake_data, x11_fake_data_len) != 0) { debug2("X11 auth data does not match fake data."); return -1; } /* Check fake data length */ if (x11_fake_data_len != x11_saved_data_len) { error("X11 fake_data_len %d != saved_data_len %d", x11_fake_data_len, x11_saved_data_len); return -1; } /* * Received authentication protocol and data match * our fake data. Substitute the fake data with real * data. */ memcpy(ucp + 12 + ((proto_len + 3) & ~3), x11_saved_data, x11_saved_data_len); return 1; } static void channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset) { int ret = x11_open_helper(&c->output); if (ret == 1) { /* Start normal processing for the channel. */ c->type = SSH_CHANNEL_OPEN; channel_pre_open_13(c, readset, writeset); } else if (ret == -1) { /* * We have received an X11 connection that has bad * authentication information. */ logit("X11 connection rejected because of wrong authentication."); buffer_clear(&c->input); buffer_clear(&c->output); channel_close_fd(&c->sock); c->sock = -1; c->type = SSH_CHANNEL_CLOSED; packet_start(SSH_MSG_CHANNEL_CLOSE); packet_put_int(c->remote_id); packet_send(); } } static void channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset) { int ret = x11_open_helper(&c->output); /* c->force_drain = 1; */ if (ret == 1) { c->type = SSH_CHANNEL_OPEN; channel_pre_open(c, readset, writeset); } else if (ret == -1) { logit("X11 connection rejected because of wrong authentication."); debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); chan_read_failed(c); buffer_clear(&c->input); chan_ibuf_empty(c); buffer_clear(&c->output); /* for proto v1, the peer will send an IEOF */ if (compat20) chan_write_failed(c); else c->type = SSH_CHANNEL_OPEN; debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); } } static void channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) { if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause && buffer_check_alloc(&c->input, CHAN_RBUF)) FD_SET(c->rfd, readset); if (c->istate == CHAN_INPUT_WAIT_DRAIN) { /* clear buffer immediately (discard any partial packet) */ buffer_clear(&c->input); chan_ibuf_empty(c); /* Start output drain. XXX just kill chan? */ chan_rcvd_oclose(c); } if (c->ostate == CHAN_OUTPUT_OPEN || c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { if (buffer_len(&c->output) > 0) FD_SET(c->wfd, writeset); else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) chan_obuf_empty(c); } } /* try to decode a socks4 header */ /* ARGSUSED */ static int channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) { char *p, *host; u_int len, have, i, found, need; char username[256]; struct { u_int8_t version; u_int8_t command; u_int16_t dest_port; struct in_addr dest_addr; } s4_req, s4_rsp; debug2("channel %d: decode socks4", c->self); have = buffer_len(&c->input); len = sizeof(s4_req); if (have < len) return 0; p = (char *)buffer_ptr(&c->input); need = 1; /* SOCKS4A uses an invalid IP address 0.0.0.x */ if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) { debug2("channel %d: socks4a request", c->self); /* ... and needs an extra string (the hostname) */ need = 2; } /* Check for terminating NUL on the string(s) */ for (found = 0, i = len; i < have; i++) { if (p[i] == '\0') { found++; if (found == need) break; } if (i > 1024) { /* the peer is probably sending garbage */ debug("channel %d: decode socks4: too long", c->self); return -1; } } if (found < need) return 0; buffer_get(&c->input, (char *)&s4_req.version, 1); buffer_get(&c->input, (char *)&s4_req.command, 1); buffer_get(&c->input, (char *)&s4_req.dest_port, 2); buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); have = buffer_len(&c->input); p = (char *)buffer_ptr(&c->input); if (memchr(p, '\0', have) == NULL) fatal("channel %d: decode socks4: user not nul terminated", c->self); len = strlen(p); debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); len++; /* trailing '\0' */ if (len > have) fatal("channel %d: decode socks4: len %d > have %d", c->self, len, have); strlcpy(username, p, sizeof(username)); buffer_consume(&c->input, len); free(c->path); c->path = NULL; if (need == 1) { /* SOCKS4: one string */ host = inet_ntoa(s4_req.dest_addr); c->path = xstrdup(host); } else { /* SOCKS4A: two strings */ have = buffer_len(&c->input); p = (char *)buffer_ptr(&c->input); len = strlen(p); debug2("channel %d: decode socks4a: host %s/%d", c->self, p, len); len++; /* trailing '\0' */ if (len > have) fatal("channel %d: decode socks4a: len %d > have %d", c->self, len, have); if (len > NI_MAXHOST) { error("channel %d: hostname \"%.100s\" too long", c->self, p); return -1; } c->path = xstrdup(p); buffer_consume(&c->input, len); } c->host_port = ntohs(s4_req.dest_port); debug2("channel %d: dynamic request: socks4 host %s port %u command %u", c->self, c->path, c->host_port, s4_req.command); if (s4_req.command != 1) { debug("channel %d: cannot handle: %s cn %d", c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); return -1; } s4_rsp.version = 0; /* vn: 0 for reply */ s4_rsp.command = 90; /* cd: req granted */ s4_rsp.dest_port = 0; /* ignored */ s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp)); return 1; } /* try to decode a socks5 header */ #define SSH_SOCKS5_AUTHDONE 0x1000 #define SSH_SOCKS5_NOAUTH 0x00 #define SSH_SOCKS5_IPV4 0x01 #define SSH_SOCKS5_DOMAIN 0x03 #define SSH_SOCKS5_IPV6 0x04 #define SSH_SOCKS5_CONNECT 0x01 #define SSH_SOCKS5_SUCCESS 0x00 /* ARGSUSED */ static int channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) { struct { u_int8_t version; u_int8_t command; u_int8_t reserved; u_int8_t atyp; } s5_req, s5_rsp; u_int16_t dest_port; char dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; u_char *p; u_int have, need, i, found, nmethods, addrlen, af; debug2("channel %d: decode socks5", c->self); p = buffer_ptr(&c->input); if (p[0] != 0x05) return -1; have = buffer_len(&c->input); if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { /* format: ver | nmethods | methods */ if (have < 2) return 0; nmethods = p[1]; if (have < nmethods + 2) return 0; /* look for method: "NO AUTHENTICATION REQUIRED" */ for (found = 0, i = 2; i < nmethods + 2; i++) { if (p[i] == SSH_SOCKS5_NOAUTH) { found = 1; break; } } if (!found) { debug("channel %d: method SSH_SOCKS5_NOAUTH not found", c->self); return -1; } buffer_consume(&c->input, nmethods + 2); buffer_put_char(&c->output, 0x05); /* version */ buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ FD_SET(c->sock, writeset); c->flags |= SSH_SOCKS5_AUTHDONE; debug2("channel %d: socks5 auth done", c->self); return 0; /* need more */ } debug2("channel %d: socks5 post auth", c->self); if (have < sizeof(s5_req)+1) return 0; /* need more */ memcpy(&s5_req, p, sizeof(s5_req)); if (s5_req.version != 0x05 || s5_req.command != SSH_SOCKS5_CONNECT || s5_req.reserved != 0x00) { debug2("channel %d: only socks5 connect supported", c->self); return -1; } switch (s5_req.atyp){ case SSH_SOCKS5_IPV4: addrlen = 4; af = AF_INET; break; case SSH_SOCKS5_DOMAIN: addrlen = p[sizeof(s5_req)]; af = -1; break; case SSH_SOCKS5_IPV6: addrlen = 16; af = AF_INET6; break; default: debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); return -1; } need = sizeof(s5_req) + addrlen + 2; if (s5_req.atyp == SSH_SOCKS5_DOMAIN) need++; if (have < need) return 0; buffer_consume(&c->input, sizeof(s5_req)); if (s5_req.atyp == SSH_SOCKS5_DOMAIN) buffer_consume(&c->input, 1); /* host string length */ buffer_get(&c->input, &dest_addr, addrlen); buffer_get(&c->input, (char *)&dest_port, 2); dest_addr[addrlen] = '\0'; free(c->path); c->path = NULL; if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { if (addrlen >= NI_MAXHOST) { error("channel %d: dynamic request: socks5 hostname " "\"%.100s\" too long", c->self, dest_addr); return -1; } c->path = xstrdup(dest_addr); } else { if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) return -1; c->path = xstrdup(ntop); } c->host_port = ntohs(dest_port); debug2("channel %d: dynamic request: socks5 host %s port %u command %u", c->self, c->path, c->host_port, s5_req.command); s5_rsp.version = 0x05; s5_rsp.command = SSH_SOCKS5_SUCCESS; s5_rsp.reserved = 0; /* ignored */ s5_rsp.atyp = SSH_SOCKS5_IPV4; dest_port = 0; /* ignored */ buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); buffer_put_int(&c->output, ntohl(INADDR_ANY)); /* bind address */ buffer_append(&c->output, &dest_port, sizeof(dest_port)); return 1; } Channel * channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect, int in, int out) { Channel *c; debug("channel_connect_stdio_fwd %s:%d", host_to_connect, port_to_connect); c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "stdio-forward", /*nonblock*/0); c->path = xstrdup(host_to_connect); c->host_port = port_to_connect; c->listening_port = 0; c->force_drain = 1; channel_register_fds(c, in, out, -1, 0, 1, 0); port_open_helper(c, "direct-tcpip"); return c; } /* dynamic port forwarding */ static void channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) { u_char *p; u_int have; int ret; have = buffer_len(&c->input); debug2("channel %d: pre_dynamic: have %d", c->self, have); /* buffer_dump(&c->input); */ /* check if the fixed size part of the packet is in buffer. */ if (have < 3) { /* need more */ FD_SET(c->sock, readset); return; } /* try to guess the protocol */ p = buffer_ptr(&c->input); switch (p[0]) { case 0x04: ret = channel_decode_socks4(c, readset, writeset); break; case 0x05: ret = channel_decode_socks5(c, readset, writeset); break; default: ret = -1; break; } if (ret < 0) { chan_mark_dead(c); } else if (ret == 0) { debug2("channel %d: pre_dynamic: need more", c->self); /* need more */ FD_SET(c->sock, readset); } else { /* switch to the next state */ c->type = SSH_CHANNEL_OPENING; port_open_helper(c, "direct-tcpip"); } } /* This is our fake X11 server socket. */ /* ARGSUSED */ static void channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; struct sockaddr_storage addr; int newsock, oerrno; socklen_t addrlen; char buf[16384], *remote_ipaddr; int remote_port; if (FD_ISSET(c->sock, readset)) { debug("X11 connection requested."); addrlen = sizeof(addr); newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (c->single_connection) { oerrno = errno; debug2("single_connection: closing X11 listener."); channel_close_fd(&c->sock); chan_mark_dead(c); errno = oerrno; } if (newsock < 0) { if (errno != EINTR && errno != EWOULDBLOCK && errno != ECONNABORTED) error("accept: %.100s", strerror(errno)); if (errno == EMFILE || errno == ENFILE) c->notbefore = monotime() + 1; return; } set_nodelay(newsock); remote_ipaddr = get_peer_ipaddr(newsock); remote_port = get_peer_port(newsock); snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", remote_ipaddr, remote_port); nc = channel_new("accepted x11 socket", SSH_CHANNEL_OPENING, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, 0, buf, 1); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring("x11"); packet_put_int(nc->self); packet_put_int(nc->local_window_max); packet_put_int(nc->local_maxpacket); /* originator ipaddr and port */ packet_put_cstring(remote_ipaddr); if (datafellows & SSH_BUG_X11FWD) { debug2("ssh2 x11 bug compat mode"); } else { packet_put_int(remote_port); } packet_send(); } else { packet_start(SSH_SMSG_X11_OPEN); packet_put_int(nc->self); if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) packet_put_cstring(buf); packet_send(); } free(remote_ipaddr); } } static void port_open_helper(Channel *c, char *rtype) { char buf[1024]; char *local_ipaddr = get_local_ipaddr(c->sock); int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1); char *remote_ipaddr = get_peer_ipaddr(c->sock); int remote_port = get_peer_port(c->sock); if (remote_port == -1) { /* Fake addr/port to appease peers that validate it (Tectia) */ free(remote_ipaddr); remote_ipaddr = xstrdup("127.0.0.1"); remote_port = 65535; } snprintf(buf, sizeof buf, "%s: listening port %d for %.100s port %d, " "connect from %.200s port %d to %.100s port %d", rtype, c->listening_port, c->path, c->host_port, remote_ipaddr, remote_port, local_ipaddr, local_port); free(c->remote_name); c->remote_name = xstrdup(buf); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring(rtype); packet_put_int(c->self); packet_put_int(c->local_window_max); packet_put_int(c->local_maxpacket); if (strcmp(rtype, "direct-tcpip") == 0) { /* target host, port */ packet_put_cstring(c->path); packet_put_int(c->host_port); } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) { /* target path */ packet_put_cstring(c->path); } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { /* listen path */ packet_put_cstring(c->path); } else { /* listen address, port */ packet_put_cstring(c->path); packet_put_int(local_port); } if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { /* reserved for future owner/mode info */ packet_put_cstring(""); } else { /* originator host and port */ packet_put_cstring(remote_ipaddr); packet_put_int((u_int)remote_port); } packet_send(); } else { packet_start(SSH_MSG_PORT_OPEN); packet_put_int(c->self); packet_put_cstring(c->path); packet_put_int(c->host_port); if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) packet_put_cstring(c->remote_name); packet_send(); } free(remote_ipaddr); free(local_ipaddr); } static void channel_set_reuseaddr(int fd) { int on = 1; /* * Set socket options. * Allow local port reuse in TIME_WAIT. */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); } void channel_set_x11_refuse_time(u_int refuse_time) { x11_refuse_time = refuse_time; } /* * This socket is listening for connections to a forwarded TCP/IP port. */ /* ARGSUSED */ static void channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; struct sockaddr_storage addr; int newsock, nextstate; socklen_t addrlen; char *rtype; if (FD_ISSET(c->sock, readset)) { debug("Connection to port %d forwarding " "to %.100s port %d requested.", c->listening_port, c->path, c->host_port); if (c->type == SSH_CHANNEL_RPORT_LISTENER) { nextstate = SSH_CHANNEL_OPENING; rtype = "forwarded-tcpip"; } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) { nextstate = SSH_CHANNEL_OPENING; rtype = "forwarded-streamlocal@openssh.com"; } else if (c->host_port == PORT_STREAMLOCAL) { nextstate = SSH_CHANNEL_OPENING; rtype = "direct-streamlocal@openssh.com"; } else if (c->host_port == 0) { nextstate = SSH_CHANNEL_DYNAMIC; rtype = "dynamic-tcpip"; } else { nextstate = SSH_CHANNEL_OPENING; rtype = "direct-tcpip"; } addrlen = sizeof(addr); newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (newsock < 0) { if (errno != EINTR && errno != EWOULDBLOCK && errno != ECONNABORTED) error("accept: %.100s", strerror(errno)); if (errno == EMFILE || errno == ENFILE) c->notbefore = monotime() + 1; return; } if (c->host_port != PORT_STREAMLOCAL) set_nodelay(newsock); nc = channel_new(rtype, nextstate, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, 0, rtype, 1); nc->listening_port = c->listening_port; nc->host_port = c->host_port; if (c->path != NULL) nc->path = xstrdup(c->path); if (nextstate != SSH_CHANNEL_DYNAMIC) port_open_helper(nc, rtype); } } /* * This is the authentication agent socket listening for connections from * clients. */ /* ARGSUSED */ static void channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; int newsock; struct sockaddr_storage addr; socklen_t addrlen; if (FD_ISSET(c->sock, readset)) { addrlen = sizeof(addr); newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (newsock < 0) { error("accept from auth socket: %.100s", strerror(errno)); if (errno == EMFILE || errno == ENFILE) c->notbefore = monotime() + 1; return; } nc = channel_new("accepted auth socket", SSH_CHANNEL_OPENING, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, 0, "accepted auth socket", 1); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring("auth-agent@openssh.com"); packet_put_int(nc->self); packet_put_int(c->local_window_max); packet_put_int(c->local_maxpacket); } else { packet_start(SSH_SMSG_AGENT_OPEN); packet_put_int(nc->self); } packet_send(); } } /* ARGSUSED */ static void channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) { int err = 0, sock; socklen_t sz = sizeof(err); if (FD_ISSET(c->sock, writeset)) { if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) { err = errno; error("getsockopt SO_ERROR failed"); } if (err == 0) { debug("channel %d: connected to %s port %d", c->self, c->connect_ctx.host, c->connect_ctx.port); channel_connect_ctx_free(&c->connect_ctx); c->type = SSH_CHANNEL_OPEN; if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(c->remote_id); packet_put_int(c->self); packet_put_int(c->local_window); packet_put_int(c->local_maxpacket); } else { packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(c->remote_id); packet_put_int(c->self); } } else { debug("channel %d: connection failed: %s", c->self, strerror(err)); /* Try next address, if any */ if ((sock = connect_next(&c->connect_ctx)) > 0) { close(c->sock); c->sock = c->rfd = c->wfd = sock; channel_max_fd = channel_find_maxfd(); return; } /* Exhausted all addresses */ error("connect_to %.100s port %d: failed.", c->connect_ctx.host, c->connect_ctx.port); channel_connect_ctx_free(&c->connect_ctx); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(c->remote_id); packet_put_int(SSH2_OPEN_CONNECT_FAILED); if (!(datafellows & SSH_BUG_OPENFAILURE)) { packet_put_cstring(strerror(err)); packet_put_cstring(""); } } else { packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(c->remote_id); } chan_mark_dead(c); } packet_send(); } } /* ARGSUSED */ static int channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset) { char buf[CHAN_RBUF]; int len, force; force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) { errno = 0; len = read(c->rfd, buf, sizeof(buf)); if (len < 0 && (errno == EINTR || ((errno == EAGAIN || errno == EWOULDBLOCK) && !force))) return 1; #ifndef PTY_ZEROREAD if (len <= 0) { #else if ((!c->isatty && len <= 0) || (c->isatty && (len < 0 || (len == 0 && errno != 0)))) { #endif debug2("channel %d: read<=0 rfd %d len %d", c->self, c->rfd, len); if (c->type != SSH_CHANNEL_OPEN) { debug2("channel %d: not open", c->self); chan_mark_dead(c); return -1; } else if (compat13) { buffer_clear(&c->output); c->type = SSH_CHANNEL_INPUT_DRAINING; debug2("channel %d: input draining.", c->self); } else { chan_read_failed(c); } return -1; } if (c->input_filter != NULL) { if (c->input_filter(c, buf, len) == -1) { debug2("channel %d: filter stops", c->self); chan_read_failed(c); } } else if (c->datagram) { buffer_put_string(&c->input, buf, len); } else { buffer_append(&c->input, buf, len); } } return 1; } /* ARGSUSED */ static int channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset) { struct termios tio; u_char *data = NULL, *buf; u_int dlen, olen = 0; int len; /* Send buffered output data to the socket. */ if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && buffer_len(&c->output) > 0) { olen = buffer_len(&c->output); if (c->output_filter != NULL) { if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { debug2("channel %d: filter stops", c->self); if (c->type != SSH_CHANNEL_OPEN) chan_mark_dead(c); else chan_write_failed(c); return -1; } } else if (c->datagram) { buf = data = buffer_get_string(&c->output, &dlen); } else { buf = data = buffer_ptr(&c->output); dlen = buffer_len(&c->output); } if (c->datagram) { /* ignore truncated writes, datagrams might get lost */ len = write(c->wfd, buf, dlen); free(data); if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return 1; if (len <= 0) { if (c->type != SSH_CHANNEL_OPEN) chan_mark_dead(c); else chan_write_failed(c); return -1; } goto out; } #ifdef _AIX /* XXX: Later AIX versions can't push as much data to tty */ if (compat20 && c->wfd_isatty) dlen = MIN(dlen, 8*1024); #endif len = write(c->wfd, buf, dlen); if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return 1; if (len <= 0) { if (c->type != SSH_CHANNEL_OPEN) { debug2("channel %d: not open", c->self); chan_mark_dead(c); return -1; } else if (compat13) { buffer_clear(&c->output); debug2("channel %d: input draining.", c->self); c->type = SSH_CHANNEL_INPUT_DRAINING; } else { chan_write_failed(c); } return -1; } #ifndef BROKEN_TCGETATTR_ICANON if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { if (tcgetattr(c->wfd, &tio) == 0 && !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { /* * Simulate echo to reduce the impact of * traffic analysis. We need to match the * size of a SSH2_MSG_CHANNEL_DATA message * (4 byte channel id + buf) */ packet_send_ignore(4 + len); packet_send(); } } #endif buffer_consume(&c->output, len); } out: if (compat20 && olen > 0) c->local_consumed += olen - buffer_len(&c->output); return 1; } static int channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) { char buf[CHAN_RBUF]; int len; /** XXX handle drain efd, too */ if (c->efd != -1) { if (c->extended_usage == CHAN_EXTENDED_WRITE && FD_ISSET(c->efd, writeset) && buffer_len(&c->extended) > 0) { len = write(c->efd, buffer_ptr(&c->extended), buffer_len(&c->extended)); debug2("channel %d: written %d to efd %d", c->self, len, c->efd); if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return 1; if (len <= 0) { debug2("channel %d: closing write-efd %d", c->self, c->efd); channel_close_fd(&c->efd); } else { buffer_consume(&c->extended, len); c->local_consumed += len; } } else if (c->efd != -1 && (c->extended_usage == CHAN_EXTENDED_READ || c->extended_usage == CHAN_EXTENDED_IGNORE) && (c->detach_close || FD_ISSET(c->efd, readset))) { len = read(c->efd, buf, sizeof(buf)); debug2("channel %d: read %d from efd %d", c->self, len, c->efd); if (len < 0 && (errno == EINTR || ((errno == EAGAIN || errno == EWOULDBLOCK) && !c->detach_close))) return 1; if (len <= 0) { debug2("channel %d: closing read-efd %d", c->self, c->efd); channel_close_fd(&c->efd); } else { if (c->extended_usage == CHAN_EXTENDED_IGNORE) { debug3("channel %d: discard efd", c->self); } else buffer_append(&c->extended, buf, len); } } } return 1; } static int channel_check_window(Channel *c) { if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && ((c->local_window_max - c->local_window > c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); packet_put_int(c->local_consumed); packet_send(); debug2("channel %d: window %d sent adjust %d", c->self, c->local_window, c->local_consumed); c->local_window += c->local_consumed; c->local_consumed = 0; } return 1; } static void channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) { channel_handle_rfd(c, readset, writeset); channel_handle_wfd(c, readset, writeset); if (!compat20) return; channel_handle_efd(c, readset, writeset); channel_check_window(c); } static u_int read_mux(Channel *c, u_int need) { char buf[CHAN_RBUF]; int len; u_int rlen; if (buffer_len(&c->input) < need) { rlen = need - buffer_len(&c->input); len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF)); if (len < 0 && (errno == EINTR || errno == EAGAIN)) return buffer_len(&c->input); if (len <= 0) { debug2("channel %d: ctl read<=0 rfd %d len %d", c->self, c->rfd, len); chan_read_failed(c); return 0; } else buffer_append(&c->input, buf, len); } return buffer_len(&c->input); } static void channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset) { u_int need; ssize_t len; if (!compat20) fatal("%s: entered with !compat20", __func__); if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) && (c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN)) { /* * Don't not read past the precise end of packets to * avoid disrupting fd passing. */ if (read_mux(c, 4) < 4) /* read header */ return; need = get_u32(buffer_ptr(&c->input)); #define CHANNEL_MUX_MAX_PACKET (256 * 1024) if (need > CHANNEL_MUX_MAX_PACKET) { debug2("channel %d: packet too big %u > %u", c->self, CHANNEL_MUX_MAX_PACKET, need); chan_rcvd_oclose(c); return; } if (read_mux(c, need + 4) < need + 4) /* read body */ return; if (c->mux_rcb(c) != 0) { debug("channel %d: mux_rcb failed", c->self); chan_mark_dead(c); return; } } if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && buffer_len(&c->output) > 0) { len = write(c->wfd, buffer_ptr(&c->output), buffer_len(&c->output)); if (len < 0 && (errno == EINTR || errno == EAGAIN)) return; if (len <= 0) { chan_mark_dead(c); return; } buffer_consume(&c->output, len); } } static void channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; struct sockaddr_storage addr; socklen_t addrlen; int newsock; uid_t euid; gid_t egid; if (!FD_ISSET(c->sock, readset)) return; debug("multiplexing control connection"); /* * Accept connection on control socket */ memset(&addr, 0, sizeof(addr)); addrlen = sizeof(addr); if ((newsock = accept(c->sock, (struct sockaddr*)&addr, &addrlen)) == -1) { error("%s accept: %s", __func__, strerror(errno)); if (errno == EMFILE || errno == ENFILE) c->notbefore = monotime() + 1; return; } if (getpeereid(newsock, &euid, &egid) < 0) { error("%s getpeereid failed: %s", __func__, strerror(errno)); close(newsock); return; } if ((euid != 0) && (getuid() != euid)) { error("multiplex uid mismatch: peer euid %u != uid %u", (u_int)euid, (u_int)getuid()); close(newsock); return; } nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, 0, "mux-control", 1); nc->mux_rcb = c->mux_rcb; debug3("%s: new mux channel %d fd %d", __func__, nc->self, nc->sock); /* establish state */ nc->mux_rcb(nc); /* mux state transitions must not elicit protocol messages */ nc->flags |= CHAN_LOCAL; } /* ARGSUSED */ static void channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) { int len; /* Send buffered output data to the socket. */ if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { len = write(c->sock, buffer_ptr(&c->output), buffer_len(&c->output)); if (len <= 0) buffer_clear(&c->output); else buffer_consume(&c->output, len); } } static void channel_handler_init_20(void) { channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; } static void channel_handler_init_13(void) { channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13; channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13; channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; } static void channel_handler_init_15(void) { channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; } static void channel_handler_init(void) { int i; for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) { channel_pre[i] = NULL; channel_post[i] = NULL; } if (compat20) channel_handler_init_20(); else if (compat13) channel_handler_init_13(); else channel_handler_init_15(); } /* gc dead channels */ static void channel_garbage_collect(Channel *c) { if (c == NULL) return; if (c->detach_user != NULL) { if (!chan_is_dead(c, c->detach_close)) return; debug2("channel %d: gc: notify user", c->self); c->detach_user(c->self, NULL); /* if we still have a callback */ if (c->detach_user != NULL) return; debug2("channel %d: gc: user detached", c->self); } if (!chan_is_dead(c, 1)) return; debug2("channel %d: garbage collecting", c->self); channel_free(c); } static void channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset, time_t *unpause_secs) { static int did_init = 0; u_int i, oalloc; Channel *c; time_t now; if (!did_init) { channel_handler_init(); did_init = 1; } now = monotime(); if (unpause_secs != NULL) *unpause_secs = 0; for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { c = channels[i]; if (c == NULL) continue; if (c->delayed) { if (ftab == channel_pre) c->delayed = 0; else continue; } if (ftab[c->type] != NULL) { /* * Run handlers that are not paused. */ if (c->notbefore <= now) (*ftab[c->type])(c, readset, writeset); else if (unpause_secs != NULL) { /* * Collect the time that the earliest * channel comes off pause. */ debug3("%s: chan %d: skip for %d more seconds", __func__, c->self, (int)(c->notbefore - now)); if (*unpause_secs == 0 || (c->notbefore - now) < *unpause_secs) *unpause_secs = c->notbefore - now; } } channel_garbage_collect(c); } if (unpause_secs != NULL && *unpause_secs != 0) debug3("%s: first channel unpauses in %d seconds", __func__, (int)*unpause_secs); } /* * Allocate/update select bitmasks and add any bits relevant to channels in * select bitmasks. */ void channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, time_t *minwait_secs, int rekeying) { u_int n, sz, nfdset; n = MAX(*maxfdp, channel_max_fd); nfdset = howmany(n+1, NFDBITS); /* Explicitly test here, because xrealloc isn't always called */ if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask)) fatal("channel_prepare_select: max_fd (%d) is too large", n); sz = nfdset * sizeof(fd_mask); /* perhaps check sz < nalloc/2 and shrink? */ if (*readsetp == NULL || sz > *nallocp) { *readsetp = xreallocarray(*readsetp, nfdset, sizeof(fd_mask)); *writesetp = xreallocarray(*writesetp, nfdset, sizeof(fd_mask)); *nallocp = sz; } *maxfdp = n; memset(*readsetp, 0, sz); memset(*writesetp, 0, sz); if (!rekeying) channel_handler(channel_pre, *readsetp, *writesetp, minwait_secs); } /* * After select, perform any appropriate operations for channels which have * events pending. */ void channel_after_select(fd_set *readset, fd_set *writeset) { channel_handler(channel_post, readset, writeset, NULL); } /* If there is data to send to the connection, enqueue some of it now. */ void channel_output_poll(void) { Channel *c; u_int i, len; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c == NULL) continue; /* * We are only interested in channels that can have buffered * incoming data. */ if (compat13) { if (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_INPUT_DRAINING) continue; } else { if (c->type != SSH_CHANNEL_OPEN) continue; } if (compat20 && (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { /* XXX is this true? */ debug3("channel %d: will not send data after close", c->self); continue; } /* Get the amount of buffered data for this channel. */ if ((c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN) && (len = buffer_len(&c->input)) > 0) { if (c->datagram) { if (len > 0) { u_char *data; u_int dlen; data = buffer_get_string(&c->input, &dlen); if (dlen > c->remote_window || dlen > c->remote_maxpacket) { debug("channel %d: datagram " "too big for channel", c->self); free(data); continue; } packet_start(SSH2_MSG_CHANNEL_DATA); packet_put_int(c->remote_id); packet_put_string(data, dlen); packet_send(); c->remote_window -= dlen; free(data); } continue; } /* * Send some data for the other side over the secure * connection. */ if (compat20) { if (len > c->remote_window) len = c->remote_window; if (len > c->remote_maxpacket) len = c->remote_maxpacket; } else { if (packet_is_interactive()) { if (len > 1024) len = 512; } else { /* Keep the packets at reasonable size. */ if (len > packet_get_maxsize()/2) len = packet_get_maxsize()/2; } } if (len > 0) { packet_start(compat20 ? SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); packet_put_int(c->remote_id); packet_put_string(buffer_ptr(&c->input), len); packet_send(); buffer_consume(&c->input, len); c->remote_window -= len; } } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { if (compat13) fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); /* * input-buffer is empty and read-socket shutdown: * tell peer, that we will not send more data: send IEOF. * hack for extended data: delay EOF if EFD still in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) debug2("channel %d: ibuf_empty delayed efd %d/(%d)", c->self, c->efd, buffer_len(&c->extended)); else chan_ibuf_empty(c); } /* Send extended data, i.e. stderr */ if (compat20 && !(c->flags & CHAN_EOF_SENT) && c->remote_window > 0 && (len = buffer_len(&c->extended)) > 0 && c->extended_usage == CHAN_EXTENDED_READ) { debug2("channel %d: rwin %u elen %u euse %d", c->self, c->remote_window, buffer_len(&c->extended), c->extended_usage); if (len > c->remote_window) len = c->remote_window; if (len > c->remote_maxpacket) len = c->remote_maxpacket; packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); packet_put_int(c->remote_id); packet_put_int(SSH2_EXTENDED_DATA_STDERR); packet_put_string(buffer_ptr(&c->extended), len); packet_send(); buffer_consume(&c->extended, len); c->remote_window -= len; debug2("channel %d: sent ext data %d", c->self, len); } } } /* -- protocol input */ /* ARGSUSED */ int channel_input_data(int type, u_int32_t seq, void *ctxt) { int id; const u_char *data; u_int data_len, win_len; Channel *c; /* Get the channel number and verify it. */ id = packet_get_int(); c = channel_lookup(id); if (c == NULL) packet_disconnect("Received data for nonexistent channel %d.", id); /* Ignore any data for non-open channels (might happen on close) */ if (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_X11_OPEN) return 0; /* Get the data. */ data = packet_get_string_ptr(&data_len); win_len = data_len; if (c->datagram) win_len += 4; /* string length header */ /* * Ignore data for protocol > 1.3 if output end is no longer open. * For protocol 2 the sending side is reducing its window as it sends * data, so we must 'fake' consumption of the data in order to ensure * that window updates are sent back. Otherwise the connection might * deadlock. */ if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { if (compat20) { c->local_window -= win_len; c->local_consumed += win_len; } return 0; } if (compat20) { if (win_len > c->local_maxpacket) { logit("channel %d: rcvd big packet %d, maxpack %d", c->self, win_len, c->local_maxpacket); } if (win_len > c->local_window) { logit("channel %d: rcvd too much data %d, win %d", c->self, win_len, c->local_window); return 0; } c->local_window -= win_len; } if (c->datagram) buffer_put_string(&c->output, data, data_len); else buffer_append(&c->output, data, data_len); packet_check_eom(); return 0; } /* ARGSUSED */ int channel_input_extended_data(int type, u_int32_t seq, void *ctxt) { int id; char *data; u_int data_len, tcode; Channel *c; /* Get the channel number and verify it. */ id = packet_get_int(); c = channel_lookup(id); if (c == NULL) packet_disconnect("Received extended_data for bad channel %d.", id); if (c->type != SSH_CHANNEL_OPEN) { logit("channel %d: ext data for non open", id); return 0; } if (c->flags & CHAN_EOF_RCVD) { if (datafellows & SSH_BUG_EXTEOF) debug("channel %d: accepting ext data after eof", id); else packet_disconnect("Received extended_data after EOF " "on channel %d.", id); } tcode = packet_get_int(); if (c->efd == -1 || c->extended_usage != CHAN_EXTENDED_WRITE || tcode != SSH2_EXTENDED_DATA_STDERR) { logit("channel %d: bad ext data", c->self); return 0; } data = packet_get_string(&data_len); packet_check_eom(); if (data_len > c->local_window) { logit("channel %d: rcvd too much extended_data %d, win %d", c->self, data_len, c->local_window); free(data); return 0; } debug2("channel %d: rcvd ext data %d", c->self, data_len); c->local_window -= data_len; buffer_append(&c->extended, data, data_len); free(data); return 0; } /* ARGSUSED */ int channel_input_ieof(int type, u_int32_t seq, void *ctxt) { int id; Channel *c; id = packet_get_int(); packet_check_eom(); c = channel_lookup(id); if (c == NULL) packet_disconnect("Received ieof for nonexistent channel %d.", id); chan_rcvd_ieof(c); /* XXX force input close */ if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { debug("channel %d: FORCE input drain", c->self); c->istate = CHAN_INPUT_WAIT_DRAIN; if (buffer_len(&c->input) == 0) chan_ibuf_empty(c); } return 0; } /* ARGSUSED */ int channel_input_close(int type, u_int32_t seq, void *ctxt) { int id; Channel *c; id = packet_get_int(); packet_check_eom(); c = channel_lookup(id); if (c == NULL) packet_disconnect("Received close for nonexistent channel %d.", id); /* * Send a confirmation that we have closed the channel and no more * data is coming for it. */ packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); packet_put_int(c->remote_id); packet_send(); /* * If the channel is in closed state, we have sent a close request, * and the other side will eventually respond with a confirmation. * Thus, we cannot free the channel here, because then there would be * no-one to receive the confirmation. The channel gets freed when * the confirmation arrives. */ if (c->type != SSH_CHANNEL_CLOSED) { /* * Not a closed channel - mark it as draining, which will * cause it to be freed later. */ buffer_clear(&c->input); c->type = SSH_CHANNEL_OUTPUT_DRAINING; } return 0; } /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ /* ARGSUSED */ int channel_input_oclose(int type, u_int32_t seq, void *ctxt) { int id = packet_get_int(); Channel *c = channel_lookup(id); packet_check_eom(); if (c == NULL) packet_disconnect("Received oclose for nonexistent channel %d.", id); chan_rcvd_oclose(c); return 0; } /* ARGSUSED */ int channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) { int id = packet_get_int(); Channel *c = channel_lookup(id); packet_check_eom(); if (c == NULL) packet_disconnect("Received close confirmation for " "out-of-range channel %d.", id); if (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED) packet_disconnect("Received close confirmation for " "non-closed channel %d (type %d).", id, c->type); channel_free(c); return 0; } /* ARGSUSED */ int channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) { int id, remote_id; Channel *c; id = packet_get_int(); c = channel_lookup(id); if (c==NULL || c->type != SSH_CHANNEL_OPENING) packet_disconnect("Received open confirmation for " "non-opening channel %d.", id); remote_id = packet_get_int(); /* Record the remote channel number and mark that the channel is now open. */ c->remote_id = remote_id; c->type = SSH_CHANNEL_OPEN; if (compat20) { c->remote_window = packet_get_int(); c->remote_maxpacket = packet_get_int(); if (c->open_confirm) { debug2("callback start"); c->open_confirm(c->self, 1, c->open_confirm_ctx); debug2("callback done"); } debug2("channel %d: open confirm rwindow %u rmax %u", c->self, c->remote_window, c->remote_maxpacket); } packet_check_eom(); return 0; } static char * reason2txt(int reason) { switch (reason) { case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED: return "administratively prohibited"; case SSH2_OPEN_CONNECT_FAILED: return "connect failed"; case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE: return "unknown channel type"; case SSH2_OPEN_RESOURCE_SHORTAGE: return "resource shortage"; } return "unknown reason"; } /* ARGSUSED */ int channel_input_open_failure(int type, u_int32_t seq, void *ctxt) { int id, reason; char *msg = NULL, *lang = NULL; Channel *c; id = packet_get_int(); c = channel_lookup(id); if (c==NULL || c->type != SSH_CHANNEL_OPENING) packet_disconnect("Received open failure for " "non-opening channel %d.", id); if (compat20) { reason = packet_get_int(); if (!(datafellows & SSH_BUG_OPENFAILURE)) { msg = packet_get_string(NULL); lang = packet_get_string(NULL); } logit("channel %d: open failed: %s%s%s", id, reason2txt(reason), msg ? ": ": "", msg ? msg : ""); free(msg); free(lang); if (c->open_confirm) { debug2("callback start"); c->open_confirm(c->self, 0, c->open_confirm_ctx); debug2("callback done"); } } packet_check_eom(); /* Schedule the channel for cleanup/deletion. */ chan_mark_dead(c); return 0; } /* ARGSUSED */ int channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) { Channel *c; int id; u_int adjust, tmp; if (!compat20) return 0; /* Get the channel number and verify it. */ id = packet_get_int(); c = channel_lookup(id); if (c == NULL) { logit("Received window adjust for non-open channel %d.", id); return 0; } adjust = packet_get_int(); packet_check_eom(); debug2("channel %d: rcvd adjust %u", id, adjust); if ((tmp = c->remote_window + adjust) < c->remote_window) fatal("channel %d: adjust %u overflows remote window %u", id, adjust, c->remote_window); c->remote_window = tmp; return 0; } /* ARGSUSED */ int channel_input_port_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; u_short host_port; char *host, *originator_string; int remote_id; remote_id = packet_get_int(); host = packet_get_string(NULL); host_port = packet_get_int(); if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) { originator_string = packet_get_string(NULL); } else { originator_string = xstrdup("unknown (remote did not supply name)"); } packet_check_eom(); c = channel_connect_to_port(host, host_port, "connected socket", originator_string); free(originator_string); free(host); if (c == NULL) { packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); packet_send(); } else c->remote_id = remote_id; return 0; } /* ARGSUSED */ int channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) { Channel *c; struct channel_confirm *cc; int id; /* Reset keepalive timeout */ packet_set_alive_timeouts(0); id = packet_get_int(); packet_check_eom(); debug2("channel_input_status_confirm: type %d id %d", type, id); if ((c = channel_lookup(id)) == NULL) { logit("channel_input_status_confirm: %d: unknown", id); return 0; } if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) return 0; cc->cb(type, c, cc->ctx); TAILQ_REMOVE(&c->status_confirms, cc, entry); explicit_bzero(cc, sizeof(*cc)); free(cc); return 0; } /* -- tcp forwarding */ void channel_set_af(int af) { IPv4or6 = af; } /* * Determine whether or not a port forward listens to loopback, the * specified address or wildcard. On the client, a specified bind * address will always override gateway_ports. On the server, a * gateway_ports of 1 (``yes'') will override the client's specification * and force a wildcard bind, whereas a value of 2 (``clientspecified'') * will bind to whatever address the client asked for. * * Special-case listen_addrs are: * * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR * "" (empty string), "*" -> wildcard v4/v6 * "localhost" -> loopback v4/v6 * "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set */ static const char * channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, int is_client, struct ForwardOptions *fwd_opts) { const char *addr = NULL; int wildcard = 0; if (listen_addr == NULL) { /* No address specified: default to gateway_ports setting */ if (fwd_opts->gateway_ports) wildcard = 1; } else if (fwd_opts->gateway_ports || is_client) { if (((datafellows & SSH_OLD_FORWARD_ADDR) && strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || (!is_client && fwd_opts->gateway_ports == 1)) { wildcard = 1; /* * Notify client if they requested a specific listen * address and it was overridden. */ if (*listen_addr != '\0' && strcmp(listen_addr, "0.0.0.0") != 0 && strcmp(listen_addr, "*") != 0) { packet_send_debug("Forwarding listen address " "\"%s\" overridden by server " "GatewayPorts", listen_addr); } } else if (strcmp(listen_addr, "localhost") != 0 || strcmp(listen_addr, "127.0.0.1") == 0 || strcmp(listen_addr, "::1") == 0) { /* Accept localhost address when GatewayPorts=yes */ addr = listen_addr; } } else if (strcmp(listen_addr, "127.0.0.1") == 0 || strcmp(listen_addr, "::1") == 0) { /* * If a specific IPv4/IPv6 localhost address has been * requested then accept it even if gateway_ports is in * effect. This allows the client to prefer IPv4 or IPv6. */ addr = listen_addr; } if (wildcardp != NULL) *wildcardp = wildcard; return addr; } static int channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, int *allocated_listen_port, struct ForwardOptions *fwd_opts) { Channel *c; int sock, r, success = 0, wildcard = 0, is_client; struct addrinfo hints, *ai, *aitop; const char *host, *addr; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; in_port_t *lport_p; is_client = (type == SSH_CHANNEL_PORT_LISTENER); if (is_client && fwd->connect_path != NULL) { host = fwd->connect_path; } else { host = (type == SSH_CHANNEL_RPORT_LISTENER) ? fwd->listen_host : fwd->connect_host; if (host == NULL) { error("No forward host name."); return 0; } if (strlen(host) >= NI_MAXHOST) { error("Forward host name too long."); return 0; } } /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ addr = channel_fwd_bind_addr(fwd->listen_host, &wildcard, is_client, fwd_opts); debug3("%s: type %d wildcard %d addr %s", __func__, type, wildcard, (addr == NULL) ? "NULL" : addr); /* * getaddrinfo returns a loopback address if the hostname is * set to NULL and hints.ai_flags is not AI_PASSIVE */ memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_flags = wildcard ? AI_PASSIVE : 0; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", fwd->listen_port); if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { if (addr == NULL) { /* This really shouldn't happen */ packet_disconnect("getaddrinfo: fatal error: %s", ssh_gai_strerror(r)); } else { error("%s: getaddrinfo(%.64s): %s", __func__, addr, ssh_gai_strerror(r)); } return 0; } if (allocated_listen_port != NULL) *allocated_listen_port = 0; for (ai = aitop; ai; ai = ai->ai_next) { switch (ai->ai_family) { case AF_INET: lport_p = &((struct sockaddr_in *)ai->ai_addr)-> sin_port; break; case AF_INET6: lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> sin6_port; break; default: continue; } /* * If allocating a port for -R forwards, then use the * same port for all address families. */ if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && allocated_listen_port != NULL && *allocated_listen_port > 0) *lport_p = htons(*allocated_listen_port); if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("%s: getnameinfo failed", __func__); continue; } /* Create a port to listen for the host. */ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { /* this is no error since kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); continue; } channel_set_reuseaddr(sock); if (ai->ai_family == AF_INET6) sock_set_v6only(sock); debug("Local forwarding listening on %s port %s.", ntop, strport); /* Bind the socket to the address. */ if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { /* address can be in use ipv6 address is already bound */ if (!ai->ai_next) error("bind: %.100s", strerror(errno)); else verbose("bind: %.100s", strerror(errno)); close(sock); continue; } /* Start listening for connections on the socket. */ if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { error("listen: %.100s", strerror(errno)); close(sock); continue; } /* * fwd->listen_port == 0 requests a dynamically allocated port - * record what we got. */ if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && allocated_listen_port != NULL && *allocated_listen_port == 0) { *allocated_listen_port = get_sock_port(sock, 1); debug("Allocated listen port %d", *allocated_listen_port); } /* Allocate a channel number for the socket. */ c = channel_new("port listener", type, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; c->listening_addr = addr == NULL ? NULL : xstrdup(addr); if (fwd->listen_port == 0 && allocated_listen_port != NULL && !(datafellows & SSH_BUG_DYNAMIC_RPORT)) c->listening_port = *allocated_listen_port; else c->listening_port = fwd->listen_port; success = 1; } if (success == 0) error("%s: cannot listen to port: %d", __func__, fwd->listen_port); freeaddrinfo(aitop); return success; } static int channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd, struct ForwardOptions *fwd_opts) { struct sockaddr_un sunaddr; const char *path; Channel *c; int port, sock; mode_t omask; switch (type) { case SSH_CHANNEL_UNIX_LISTENER: if (fwd->connect_path != NULL) { if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) { error("Local connecting path too long: %s", fwd->connect_path); return 0; } path = fwd->connect_path; port = PORT_STREAMLOCAL; } else { if (fwd->connect_host == NULL) { error("No forward host name."); return 0; } if (strlen(fwd->connect_host) >= NI_MAXHOST) { error("Forward host name too long."); return 0; } path = fwd->connect_host; port = fwd->connect_port; } break; case SSH_CHANNEL_RUNIX_LISTENER: path = fwd->listen_path; port = PORT_STREAMLOCAL; break; default: error("%s: unexpected channel type %d", __func__, type); return 0; } if (fwd->listen_path == NULL) { error("No forward path name."); return 0; } if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) { error("Local listening path too long: %s", fwd->listen_path); return 0; } debug3("%s: type %d path %s", __func__, type, fwd->listen_path); /* Start a Unix domain listener. */ omask = umask(fwd_opts->streamlocal_bind_mask); sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG, fwd_opts->streamlocal_bind_unlink); umask(omask); if (sock < 0) return 0; debug("Local forwarding listening on path %s.", fwd->listen_path); /* Allocate a channel number for the socket. */ c = channel_new("unix listener", type, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "unix listener", 1); c->path = xstrdup(path); c->host_port = port; c->listening_port = PORT_STREAMLOCAL; c->listening_addr = xstrdup(fwd->listen_path); return 1; } static int channel_cancel_rport_listener_tcpip(const char *host, u_short port) { u_int i; int found = 0; for (i = 0; i < channels_alloc; i++) { Channel *c = channels[i]; if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) continue; if (strcmp(c->path, host) == 0 && c->listening_port == port) { debug2("%s: close channel %d", __func__, i); channel_free(c); found = 1; } } return (found); } static int channel_cancel_rport_listener_streamlocal(const char *path) { u_int i; int found = 0; for (i = 0; i < channels_alloc; i++) { Channel *c = channels[i]; if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) continue; if (c->path == NULL) continue; if (strcmp(c->path, path) == 0) { debug2("%s: close channel %d", __func__, i); channel_free(c); found = 1; } } return (found); } int channel_cancel_rport_listener(struct Forward *fwd) { if (fwd->listen_path != NULL) return channel_cancel_rport_listener_streamlocal(fwd->listen_path); else return channel_cancel_rport_listener_tcpip(fwd->listen_host, fwd->listen_port); } static int channel_cancel_lport_listener_tcpip(const char *lhost, u_short lport, int cport, struct ForwardOptions *fwd_opts) { u_int i; int found = 0; const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts); for (i = 0; i < channels_alloc; i++) { Channel *c = channels[i]; if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) continue; if (c->listening_port != lport) continue; if (cport == CHANNEL_CANCEL_PORT_STATIC) { /* skip dynamic forwardings */ if (c->host_port == 0) continue; } else { if (c->host_port != cport) continue; } if ((c->listening_addr == NULL && addr != NULL) || (c->listening_addr != NULL && addr == NULL)) continue; if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { debug2("%s: close channel %d", __func__, i); channel_free(c); found = 1; } } return (found); } static int channel_cancel_lport_listener_streamlocal(const char *path) { u_int i; int found = 0; if (path == NULL) { error("%s: no path specified.", __func__); return 0; } for (i = 0; i < channels_alloc; i++) { Channel *c = channels[i]; if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) continue; if (c->listening_addr == NULL) continue; if (strcmp(c->listening_addr, path) == 0) { debug2("%s: close channel %d", __func__, i); channel_free(c); found = 1; } } return (found); } int channel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts) { if (fwd->listen_path != NULL) return channel_cancel_lport_listener_streamlocal(fwd->listen_path); else return channel_cancel_lport_listener_tcpip(fwd->listen_host, fwd->listen_port, cport, fwd_opts); } /* protocol local port fwd, used by ssh (and sshd in v1) */ int channel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts) { if (fwd->listen_path != NULL) { return channel_setup_fwd_listener_streamlocal( SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts); } else { return channel_setup_fwd_listener_tcpip(SSH_CHANNEL_PORT_LISTENER, fwd, NULL, fwd_opts); } } /* protocol v2 remote port fwd, used by sshd */ int channel_setup_remote_fwd_listener(struct Forward *fwd, int *allocated_listen_port, struct ForwardOptions *fwd_opts) { if (fwd->listen_path != NULL) { return channel_setup_fwd_listener_streamlocal( SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts); } else { return channel_setup_fwd_listener_tcpip( SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port, fwd_opts); } } /* * Translate the requested rfwd listen host to something usable for * this server. */ static const char * channel_rfwd_bind_host(const char *listen_host) { if (listen_host == NULL) { if (datafellows & SSH_BUG_RFWD_ADDR) return "127.0.0.1"; else return "localhost"; } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) { if (datafellows & SSH_BUG_RFWD_ADDR) return "0.0.0.0"; else return ""; } else return listen_host; } /* * Initiate forwarding of connections to port "port" on remote host through * the secure channel to host:port from local side. * Returns handle (index) for updating the dynamic listen port with * channel_update_permitted_opens(). */ int channel_request_remote_forwarding(struct Forward *fwd) { int type, success = 0, idx = -1; /* Send the forward request to the remote side. */ if (compat20) { packet_start(SSH2_MSG_GLOBAL_REQUEST); if (fwd->listen_path != NULL) { packet_put_cstring("streamlocal-forward@openssh.com"); packet_put_char(1); /* boolean: want reply */ packet_put_cstring(fwd->listen_path); } else { packet_put_cstring("tcpip-forward"); packet_put_char(1); /* boolean: want reply */ packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host)); packet_put_int(fwd->listen_port); } packet_send(); packet_write_wait(); /* Assume that server accepts the request */ success = 1; } else if (fwd->listen_path == NULL) { packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); packet_put_int(fwd->listen_port); packet_put_cstring(fwd->connect_host); packet_put_int(fwd->connect_port); packet_send(); packet_write_wait(); /* Wait for response from the remote side. */ type = packet_read(); switch (type) { case SSH_SMSG_SUCCESS: success = 1; break; case SSH_SMSG_FAILURE: break; default: /* Unknown packet */ packet_disconnect("Protocol error for port forward request:" "received packet type %d.", type); } } else { logit("Warning: Server does not support remote stream local forwarding."); } if (success) { /* Record that connection to this host/port is permitted. */ permitted_opens = xreallocarray(permitted_opens, num_permitted_opens + 1, sizeof(*permitted_opens)); idx = num_permitted_opens++; if (fwd->connect_path != NULL) { permitted_opens[idx].host_to_connect = xstrdup(fwd->connect_path); permitted_opens[idx].port_to_connect = PORT_STREAMLOCAL; } else { permitted_opens[idx].host_to_connect = xstrdup(fwd->connect_host); permitted_opens[idx].port_to_connect = fwd->connect_port; } if (fwd->listen_path != NULL) { permitted_opens[idx].listen_host = NULL; permitted_opens[idx].listen_path = xstrdup(fwd->listen_path); permitted_opens[idx].listen_port = PORT_STREAMLOCAL; } else { permitted_opens[idx].listen_host = fwd->listen_host ? xstrdup(fwd->listen_host) : NULL; permitted_opens[idx].listen_path = NULL; permitted_opens[idx].listen_port = fwd->listen_port; } } return (idx); } static int open_match(ForwardPermission *allowed_open, const char *requestedhost, int requestedport) { if (allowed_open->host_to_connect == NULL) return 0; if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT && allowed_open->port_to_connect != requestedport) return 0; if (strcmp(allowed_open->host_to_connect, requestedhost) != 0) return 0; return 1; } /* * Note that in the listen host/port case * we don't support FWD_PERMIT_ANY_PORT and * need to translate between the configured-host (listen_host) * and what we've sent to the remote server (channel_rfwd_bind_host) */ static int open_listen_match_tcpip(ForwardPermission *allowed_open, const char *requestedhost, u_short requestedport, int translate) { const char *allowed_host; if (allowed_open->host_to_connect == NULL) return 0; if (allowed_open->listen_port != requestedport) return 0; if (!translate && allowed_open->listen_host == NULL && requestedhost == NULL) return 1; allowed_host = translate ? channel_rfwd_bind_host(allowed_open->listen_host) : allowed_open->listen_host; if (allowed_host == NULL || strcmp(allowed_host, requestedhost) != 0) return 0; return 1; } static int open_listen_match_streamlocal(ForwardPermission *allowed_open, const char *requestedpath) { if (allowed_open->host_to_connect == NULL) return 0; if (allowed_open->listen_port != PORT_STREAMLOCAL) return 0; if (allowed_open->listen_path == NULL || strcmp(allowed_open->listen_path, requestedpath) != 0) return 0; return 1; } /* * Request cancellation of remote forwarding of connection host:port from * local side. */ static int channel_request_rforward_cancel_tcpip(const char *host, u_short port) { int i; if (!compat20) return -1; for (i = 0; i < num_permitted_opens; i++) { if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0)) break; } if (i >= num_permitted_opens) { debug("%s: requested forward not found", __func__); return -1; } packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("cancel-tcpip-forward"); packet_put_char(0); packet_put_cstring(channel_rfwd_bind_host(host)); packet_put_int(port); packet_send(); permitted_opens[i].listen_port = 0; permitted_opens[i].port_to_connect = 0; free(permitted_opens[i].host_to_connect); permitted_opens[i].host_to_connect = NULL; free(permitted_opens[i].listen_host); permitted_opens[i].listen_host = NULL; permitted_opens[i].listen_path = NULL; return 0; } /* * Request cancellation of remote forwarding of Unix domain socket * path from local side. */ static int channel_request_rforward_cancel_streamlocal(const char *path) { int i; if (!compat20) return -1; for (i = 0; i < num_permitted_opens; i++) { if (open_listen_match_streamlocal(&permitted_opens[i], path)) break; } if (i >= num_permitted_opens) { debug("%s: requested forward not found", __func__); return -1; } packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("cancel-streamlocal-forward@openssh.com"); packet_put_char(0); packet_put_cstring(path); packet_send(); permitted_opens[i].listen_port = 0; permitted_opens[i].port_to_connect = 0; free(permitted_opens[i].host_to_connect); permitted_opens[i].host_to_connect = NULL; permitted_opens[i].listen_host = NULL; free(permitted_opens[i].listen_path); permitted_opens[i].listen_path = NULL; return 0; } /* * Request cancellation of remote forwarding of a connection from local side. */ int channel_request_rforward_cancel(struct Forward *fwd) { if (fwd->listen_path != NULL) { return (channel_request_rforward_cancel_streamlocal( fwd->listen_path)); } else { return (channel_request_rforward_cancel_tcpip(fwd->listen_host, fwd->listen_port ? fwd->listen_port : fwd->allocated_port)); } } /* * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates * listening for the port, and sends back a success reply (or disconnect * message if there was an error). */ int channel_input_port_forward_request(int is_root, struct ForwardOptions *fwd_opts) { int success = 0; struct Forward fwd; /* Get arguments from the packet. */ memset(&fwd, 0, sizeof(fwd)); fwd.listen_port = packet_get_int(); fwd.connect_host = packet_get_string(NULL); fwd.connect_port = packet_get_int(); #ifndef HAVE_CYGWIN /* * Check that an unprivileged user is not trying to forward a * privileged port. */ if (fwd.listen_port < IPPORT_RESERVED && !is_root) packet_disconnect( "Requested forwarding of port %d but user is not root.", fwd.listen_port); if (fwd.connect_port == 0) packet_disconnect("Dynamic forwarding denied."); #endif /* Initiate forwarding */ success = channel_setup_local_fwd_listener(&fwd, fwd_opts); /* Free the argument string. */ free(fwd.connect_host); return (success ? 0 : -1); } /* * Permits opening to any host/port if permitted_opens[] is empty. This is * usually called by the server, because the user could connect to any port * anyway, and the server has no way to know but to trust the client anyway. */ void channel_permit_all_opens(void) { if (num_permitted_opens == 0) all_opens_permitted = 1; } void channel_add_permitted_opens(char *host, int port) { debug("allow port forwarding to host %s port %d", host, port); permitted_opens = xreallocarray(permitted_opens, num_permitted_opens + 1, sizeof(*permitted_opens)); permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); permitted_opens[num_permitted_opens].port_to_connect = port; permitted_opens[num_permitted_opens].listen_host = NULL; permitted_opens[num_permitted_opens].listen_path = NULL; permitted_opens[num_permitted_opens].listen_port = 0; num_permitted_opens++; all_opens_permitted = 0; } /* * Update the listen port for a dynamic remote forward, after * the actual 'newport' has been allocated. If 'newport' < 0 is * passed then they entry will be invalidated. */ void channel_update_permitted_opens(int idx, int newport) { if (idx < 0 || idx >= num_permitted_opens) { debug("channel_update_permitted_opens: index out of range:" " %d num_permitted_opens %d", idx, num_permitted_opens); return; } debug("%s allowed port %d for forwarding to host %s port %d", newport > 0 ? "Updating" : "Removing", newport, permitted_opens[idx].host_to_connect, permitted_opens[idx].port_to_connect); if (newport >= 0) { permitted_opens[idx].listen_port = (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; } else { permitted_opens[idx].listen_port = 0; permitted_opens[idx].port_to_connect = 0; free(permitted_opens[idx].host_to_connect); permitted_opens[idx].host_to_connect = NULL; free(permitted_opens[idx].listen_host); permitted_opens[idx].listen_host = NULL; free(permitted_opens[idx].listen_path); permitted_opens[idx].listen_path = NULL; } } int channel_add_adm_permitted_opens(char *host, int port) { debug("config allows port forwarding to host %s port %d", host, port); permitted_adm_opens = xreallocarray(permitted_adm_opens, num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); permitted_adm_opens[num_adm_permitted_opens].host_to_connect = xstrdup(host); permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; permitted_adm_opens[num_adm_permitted_opens].listen_host = NULL; permitted_adm_opens[num_adm_permitted_opens].listen_path = NULL; permitted_adm_opens[num_adm_permitted_opens].listen_port = 0; return ++num_adm_permitted_opens; } void channel_disable_adm_local_opens(void) { channel_clear_adm_permitted_opens(); permitted_adm_opens = xcalloc(sizeof(*permitted_adm_opens), 1); permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL; num_adm_permitted_opens = 1; } void channel_clear_permitted_opens(void) { int i; for (i = 0; i < num_permitted_opens; i++) { free(permitted_opens[i].host_to_connect); free(permitted_opens[i].listen_host); free(permitted_opens[i].listen_path); } free(permitted_opens); permitted_opens = NULL; num_permitted_opens = 0; } void channel_clear_adm_permitted_opens(void) { int i; for (i = 0; i < num_adm_permitted_opens; i++) { free(permitted_adm_opens[i].host_to_connect); free(permitted_adm_opens[i].listen_host); free(permitted_adm_opens[i].listen_path); } free(permitted_adm_opens); permitted_adm_opens = NULL; num_adm_permitted_opens = 0; } void channel_print_adm_permitted_opens(void) { int i; printf("permitopen"); if (num_adm_permitted_opens == 0) { printf(" any\n"); return; } for (i = 0; i < num_adm_permitted_opens; i++) if (permitted_adm_opens[i].host_to_connect == NULL) printf(" none"); else printf(" %s:%d", permitted_adm_opens[i].host_to_connect, permitted_adm_opens[i].port_to_connect); printf("\n"); } /* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */ int permitopen_port(const char *p) { int port; if (strcmp(p, "*") == 0) return FWD_PERMIT_ANY_PORT; if ((port = a2port(p)) > 0) return port; return -1; } /* Try to start non-blocking connect to next host in cctx list */ static int connect_next(struct channel_connect *cctx) { int sock, saved_errno; struct sockaddr_un *sunaddr; char ntop[NI_MAXHOST], strport[MAX(NI_MAXSERV,sizeof(sunaddr->sun_path))]; for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { switch (cctx->ai->ai_family) { case AF_UNIX: /* unix:pathname instead of host:port */ sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr; strlcpy(ntop, "unix", sizeof(ntop)); strlcpy(strport, sunaddr->sun_path, sizeof(strport)); break; case AF_INET: case AF_INET6: if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("connect_next: getnameinfo failed"); continue; } break; default: continue; } if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, cctx->ai->ai_protocol)) == -1) { if (cctx->ai->ai_next == NULL) error("socket: %.100s", strerror(errno)); else verbose("socket: %.100s", strerror(errno)); continue; } if (set_nonblock(sock) == -1) fatal("%s: set_nonblock(%d)", __func__, sock); if (connect(sock, cctx->ai->ai_addr, cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { debug("connect_next: host %.100s ([%.100s]:%s): " "%.100s", cctx->host, ntop, strport, strerror(errno)); saved_errno = errno; close(sock); errno = saved_errno; continue; /* fail -- try next */ } if (cctx->ai->ai_family != AF_UNIX) set_nodelay(sock); debug("connect_next: host %.100s ([%.100s]:%s) " "in progress, fd=%d", cctx->host, ntop, strport, sock); cctx->ai = cctx->ai->ai_next; return sock; } return -1; } static void channel_connect_ctx_free(struct channel_connect *cctx) { free(cctx->host); if (cctx->aitop) { if (cctx->aitop->ai_family == AF_UNIX) free(cctx->aitop); else freeaddrinfo(cctx->aitop); } memset(cctx, 0, sizeof(*cctx)); } /* Return CONNECTING channel to remote host:port or local socket path */ static Channel * connect_to(const char *name, int port, char *ctype, char *rname) { struct addrinfo hints; int gaierr; int sock = -1; char strport[NI_MAXSERV]; struct channel_connect cctx; Channel *c; memset(&cctx, 0, sizeof(cctx)); if (port == PORT_STREAMLOCAL) { struct sockaddr_un *sunaddr; struct addrinfo *ai; if (strlen(name) > sizeof(sunaddr->sun_path)) { error("%.100s: %.100s", name, strerror(ENAMETOOLONG)); return (NULL); } /* * Fake up a struct addrinfo for AF_UNIX connections. * channel_connect_ctx_free() must check ai_family * and use free() not freeaddirinfo() for AF_UNIX. */ ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr)); memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr)); ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(*sunaddr); ai->ai_family = AF_UNIX; ai->ai_socktype = SOCK_STREAM; ai->ai_protocol = PF_UNSPEC; sunaddr = (struct sockaddr_un *)ai->ai_addr; sunaddr->sun_family = AF_UNIX; strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); cctx.aitop = ai; } else { memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", port); if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop)) != 0) { error("connect_to %.100s: unknown host (%s)", name, ssh_gai_strerror(gaierr)); return NULL; } } cctx.host = xstrdup(name); cctx.port = port; cctx.ai = cctx.aitop; if ((sock = connect_next(&cctx)) == -1) { error("connect to %.100s port %d failed: %s", name, port, strerror(errno)); channel_connect_ctx_free(&cctx); return NULL; } c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1); c->connect_ctx = cctx; return c; } Channel * channel_connect_by_listen_address(const char *listen_host, u_short listen_port, char *ctype, char *rname) { int i; for (i = 0; i < num_permitted_opens; i++) { if (open_listen_match_tcpip(&permitted_opens[i], listen_host, listen_port, 1)) { return connect_to( permitted_opens[i].host_to_connect, permitted_opens[i].port_to_connect, ctype, rname); } } error("WARNING: Server requests forwarding for unknown listen_port %d", listen_port); return NULL; } Channel * channel_connect_by_listen_path(const char *path, char *ctype, char *rname) { int i; for (i = 0; i < num_permitted_opens; i++) { if (open_listen_match_streamlocal(&permitted_opens[i], path)) { return connect_to( permitted_opens[i].host_to_connect, permitted_opens[i].port_to_connect, ctype, rname); } } error("WARNING: Server requests forwarding for unknown path %.100s", path); return NULL; } /* Check if connecting to that port is permitted and connect. */ Channel * channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname) { int i, permit, permit_adm = 1; permit = all_opens_permitted; if (!permit) { for (i = 0; i < num_permitted_opens; i++) if (open_match(&permitted_opens[i], host, port)) { permit = 1; break; } } if (num_adm_permitted_opens > 0) { permit_adm = 0; for (i = 0; i < num_adm_permitted_opens; i++) if (open_match(&permitted_adm_opens[i], host, port)) { permit_adm = 1; break; } } if (!permit || !permit_adm) { logit("Received request to connect to host %.100s port %d, " "but the request was denied.", host, port); return NULL; } return connect_to(host, port, ctype, rname); } /* Check if connecting to that path is permitted and connect. */ Channel * channel_connect_to_path(const char *path, char *ctype, char *rname) { int i, permit, permit_adm = 1; permit = all_opens_permitted; if (!permit) { for (i = 0; i < num_permitted_opens; i++) if (open_match(&permitted_opens[i], path, PORT_STREAMLOCAL)) { permit = 1; break; } } if (num_adm_permitted_opens > 0) { permit_adm = 0; for (i = 0; i < num_adm_permitted_opens; i++) if (open_match(&permitted_adm_opens[i], path, PORT_STREAMLOCAL)) { permit_adm = 1; break; } } if (!permit || !permit_adm) { logit("Received request to connect to path %.100s, " "but the request was denied.", path); return NULL; } return connect_to(path, PORT_STREAMLOCAL, ctype, rname); } void channel_send_window_changes(void) { u_int i; struct winsize ws; for (i = 0; i < channels_alloc; i++) { if (channels[i] == NULL || !channels[i]->client_tty || channels[i]->type != SSH_CHANNEL_OPEN) continue; if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) continue; channel_request_start(i, "window-change", 0); packet_put_int((u_int)ws.ws_col); packet_put_int((u_int)ws.ws_row); packet_put_int((u_int)ws.ws_xpixel); packet_put_int((u_int)ws.ws_ypixel); packet_send(); } } /* -- X11 forwarding */ /* * Creates an internet domain socket for listening for X11 connections. * Returns 0 and a suitable display number for the DISPLAY variable * stored in display_numberp , or -1 if an error occurs. */ int x11_create_display_inet(int x11_display_offset, int x11_use_localhost, int single_connection, u_int *display_numberp, int **chanids) { Channel *nc = NULL; int display_number, sock; u_short port; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; if (chanids == NULL) return -1; for (display_number = x11_display_offset; display_number < MAX_DISPLAYS; display_number++) { port = 6000 + display_number; memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", port); if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr)); return -1; } for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT) #ifdef EPFNOSUPPORT && (errno != EPFNOSUPPORT) #endif ) { error("socket: %.100s", strerror(errno)); freeaddrinfo(aitop); return -1; } else { debug("x11_create_display_inet: Socket family %d not supported", ai->ai_family); continue; } } if (ai->ai_family == AF_INET6) sock_set_v6only(sock); if (x11_use_localhost) channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); for (n = 0; n < num_socks; n++) { close(socks[n]); } num_socks = 0; break; } socks[num_socks++] = sock; if (num_socks == NUM_SOCKS) break; } freeaddrinfo(aitop); if (num_socks > 0) break; } if (display_number >= MAX_DISPLAYS) { error("Failed to allocate internet-domain X11 display socket."); return -1; } /* Start listening for connections on the socket. */ for (n = 0; n < num_socks; n++) { sock = socks[n]; if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { error("listen: %.100s", strerror(errno)); close(sock); return -1; } } /* Allocate a channel for each socket. */ *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); for (n = 0; n < num_socks; n++) { sock = socks[n]; nc = channel_new("x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; } (*chanids)[n] = -1; /* Return the display number for the DISPLAY environment variable. */ *display_numberp = display_number; return (0); } static int connect_local_xsocket_path(const char *pathname) { int sock; struct sockaddr_un addr; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) error("socket: %.100s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) return sock; close(sock); error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } static int connect_local_xsocket(u_int dnr) { char buf[1024]; snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); return connect_local_xsocket_path(buf); } int x11_connect_display(void) { u_int display_number; const char *display; char buf[1024], *cp; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, sock = 0; /* Try to open a socket for the local X server. */ display = getenv("DISPLAY"); if (!display) { error("DISPLAY not set."); return -1; } /* * Now we decode the value of the DISPLAY variable and make a * connection to the real X server. */ /* Check if the display is from launchd. */ #ifdef __APPLE__ if (strncmp(display, "/tmp/launch", 11) == 0) { sock = connect_local_xsocket_path(display); if (sock < 0) return -1; /* OK, we now have a connection to the display. */ return sock; } #endif /* * Check if it is a unix domain socket. Unix domain displays are in * one of the following formats: unix:d[.s], :d[.s], ::d[.s] */ if (strncmp(display, "unix:", 5) == 0 || display[0] == ':') { /* Connect to the unix domain socket. */ if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) { error("Could not parse display number from DISPLAY: %.100s", display); return -1; } /* Create a socket. */ sock = connect_local_xsocket(display_number); if (sock < 0) return -1; /* OK, we now have a connection to the display. */ return sock; } /* * Connect to an inet socket. The DISPLAY value is supposedly * hostname:d[.s], where hostname may also be numeric IP address. */ strlcpy(buf, display, sizeof(buf)); cp = strchr(buf, ':'); if (!cp) { error("Could not find ':' in DISPLAY: %.100s", display); return -1; } *cp = 0; /* buf now contains the host name. But first we parse the display number. */ if (sscanf(cp + 1, "%u", &display_number) != 1) { error("Could not parse display number from DISPLAY: %.100s", display); return -1; } /* Look up the host address */ memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", 6000 + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); return -1; } for (ai = aitop; ai; ai = ai->ai_next) { /* Create a socket. */ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { debug2("socket: %.100s", strerror(errno)); continue; } /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("connect %.100s port %u: %.100s", buf, 6000 + display_number, strerror(errno)); close(sock); continue; } /* Success */ break; } freeaddrinfo(aitop); if (!ai) { error("connect %.100s port %u: %.100s", buf, 6000 + display_number, strerror(errno)); return -1; } set_nodelay(sock); return sock; } /* * This is called when SSH_SMSG_X11_OPEN is received. The packet contains * the remote channel number. We should do whatever we want, and respond * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. */ /* ARGSUSED */ int x11_input_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; int remote_id, sock = 0; char *remote_host; debug("Received X11 open request."); remote_id = packet_get_int(); if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) { remote_host = packet_get_string(NULL); } else { remote_host = xstrdup("unknown (remote did not supply name)"); } packet_check_eom(); /* Obtain a connection to the real X display. */ sock = x11_connect_display(); if (sock != -1) { /* Allocate a channel for this connection. */ c = channel_new("connected x11 socket", SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0, remote_host, 1); c->remote_id = remote_id; c->force_drain = 1; } free(remote_host); if (c == NULL) { /* Send refusal to the remote host. */ packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); } else { /* Send a confirmation to the remote host. */ packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(remote_id); packet_put_int(c->self); } packet_send(); return 0; } /* dummy protocol handler that denies SSH-1 requests (agent/x11) */ /* ARGSUSED */ int deny_input_open(int type, u_int32_t seq, void *ctxt) { int rchan = packet_get_int(); switch (type) { case SSH_SMSG_AGENT_OPEN: error("Warning: ssh server tried agent forwarding."); break; case SSH_SMSG_X11_OPEN: error("Warning: ssh server tried X11 forwarding."); break; default: error("deny_input_open: type %d", type); break; } error("Warning: this is probably a break-in attempt by a malicious server."); packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_send(); return 0; } /* * Requests forwarding of X11 connections, generates fake authentication * data, and enables authentication spoofing. * This should be called in the client only. */ void x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, const char *proto, const char *data, int want_reply) { u_int data_len = (u_int) strlen(data) / 2; u_int i, value; char *new_data; int screen_number; const char *cp; u_int32_t rnd = 0; if (x11_saved_display == NULL) x11_saved_display = xstrdup(disp); else if (strcmp(disp, x11_saved_display) != 0) { error("x11_request_forwarding_with_spoofing: different " "$DISPLAY already forwarded"); return; } cp = strchr(disp, ':'); if (cp) cp = strchr(cp, '.'); if (cp) screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL); else screen_number = 0; if (x11_saved_proto == NULL) { /* Save protocol name. */ x11_saved_proto = xstrdup(proto); /* * Extract real authentication data and generate fake data * of the same length. */ x11_saved_data = xmalloc(data_len); x11_fake_data = xmalloc(data_len); for (i = 0; i < data_len; i++) { if (sscanf(data + 2 * i, "%2x", &value) != 1) fatal("x11_request_forwarding: bad " "authentication data: %.100s", data); if (i % 4 == 0) rnd = arc4random(); x11_saved_data[i] = value; x11_fake_data[i] = rnd & 0xff; rnd >>= 8; } x11_saved_data_len = data_len; x11_fake_data_len = data_len; } /* Convert the fake data into hex. */ new_data = tohex(x11_fake_data, data_len); /* Send the request packet. */ if (compat20) { channel_request_start(client_session_id, "x11-req", want_reply); packet_put_char(0); /* XXX bool single connection */ } else { packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); } packet_put_cstring(proto); packet_put_cstring(new_data); packet_put_int(screen_number); packet_send(); packet_write_wait(); free(new_data); } /* -- agent forwarding */ /* Sends a message to the server to request authentication fd forwarding. */ void auth_request_forwarding(void) { packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); packet_send(); packet_write_wait(); } openssh-7.2p2/contrib004075500017500001750000000000001267006270000130365ustar00djmdjmopenssh-7.2p2/contrib/Makefile010064400017500001750000000010231267006270000145460ustar00djmdjmPKG_CONFIG = pkg-config all: @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" gnome-ssh-askpass1: gnome-ssh-askpass1.c $(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \ gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ `gnome-config --libs gnome gnomeui` gnome-ssh-askpass2: gnome-ssh-askpass2.c $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gtk+-2.0` \ gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ `$(PKG_CONFIG) --libs gtk+-2.0 x11` clean: rm -f *.o gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssh-askpass openssh-7.2p2/contrib/README010064400017500001750000000033601267006270000137740ustar00djmdjmOther patches and addons for OpenSSH. Please send submissions to djm@mindrot.org Externally maintained --------------------- SSH Proxy Command -- connect.c Shun-ichi GOTO has written a very useful ProxyCommand which allows the use of outbound SSH from behind a SOCKS4, SOCKS5 or https CONNECT style proxy server. His page for connect.c has extensive documentation on its use as well as compiled versions for Win32. https://bitbucket.org/gotoh/connect/wiki/Home X11 SSH Askpass: Jim Knoble has written an excellent X11 passphrase requester. This is highly recommended: http://www.jmknoble.net/software/x11-ssh-askpass/ In this directory ----------------- ssh-copy-id: Phil Hands' shell script to automate the process of adding your public key to a remote machine's ~/.ssh/authorized_keys file. gnome-ssh-askpass[12]: A GNOME and Gtk2 passphrase requesters. Use "make gnome-ssh-askpass1" or "make gnome-ssh-askpass2" to build. sshd.pam.generic: A generic PAM config file which may be useful on your system. YMMV sshd.pam.freebsd: A PAM config file which works with FreeBSD's PAM port. Contributed by Dominik Brettnacher findssl.sh: Search for all instances of OpenSSL headers and libraries and print their versions. This is intended to help diagnose OpenSSH's "OpenSSL headers do not match your library" errors. aix: Files to build an AIX native (installp or SMIT installable) package. caldera: RPM spec file and scripts for building Caldera OpenLinuix packages cygwin: Support files for Cygwin hpux: Support files for HP-UX redhat: RPM spec file and scripts for building Redhat packages suse: RPM spec file and scripts for building SuSE packages openssh-7.2p2/contrib/aix004075500017500001750000000000001267006270000136175ustar00djmdjmopenssh-7.2p2/contrib/aix/README010064400017500001750000000025101267006270000145510ustar00djmdjmOverview: This directory contains files to build an AIX native (installp or SMIT installable) openssh package. Directions: (optional) create config.local in your build dir ./configure [options] contrib/aix/buildbff.sh The file config.local or the environment is read to set the following options (default first): PERMIT_ROOT_LOGIN=[no|yes] X11_FORWARDING=[no|yes] AIX_SRC=[no|yes] Acknowledgements: The contents of this directory are based on Ben Lindstrom's Solaris buildpkg.sh. Ben also supplied inventory.sh. Jim Abbey's (GPL'ed) lppbuild-2.1 was used to learn how to build .bff's and for comparison with the output from this script, however no code from lppbuild is included and it is not required for operation. SRC support based on examples provided by Sandor Sklar and Maarten Kreuger. PrivSep account handling fixes contributed by W. Earl Allen. Other notes: The script treats all packages as USR packages (not ROOT+USR when appropriate). It seems to work, though...... If there are any patches to this that have not yet been integrated they may be found at http://www.zip.com.au/~dtucker/openssh/. Disclaimer: It is hoped that it is useful but there is no warranty. If it breaks you get to keep both pieces. - Darren Tucker (dtucker at zip dot com dot au) 2002/03/01 $Id: README,v 1.4 2003/08/25 05:01:04 dtucker Exp $ openssh-7.2p2/contrib/aix/buildbff.sh010075500017500001750000000224561267006270000160200ustar00djmdjm#!/bin/sh # # buildbff.sh: Create AIX SMIT-installable OpenSSH packages # $Id: buildbff.sh,v 1.13 2011/05/05 03:48:41 djm Exp $ # # Author: Darren Tucker (dtucker at zip dot com dot au) # This file is placed in the public domain and comes with absolutely # no warranty. # # Based originally on Ben Lindstrom's buildpkg.sh for Solaris # # # Tunable configuration settings # create a "config.local" in your build directory or set # environment variables to override these. # [ -z "$PERMIT_ROOT_LOGIN" ] && PERMIT_ROOT_LOGIN=no [ -z "$X11_FORWARDING" ] && X11_FORWARDING=no [ -z "$AIX_SRC" ] && AIX_SRC=no umask 022 startdir=`pwd` perl -v >/dev/null || (echo perl required; exit 1) # Path to inventory.sh: same place as buildbff.sh if echo $0 | egrep '^/' then inventory=`dirname $0`/inventory.sh # absolute path else inventory=`pwd`/`dirname $0`/inventory.sh # relative path fi # # We still support running from contrib/aix, but this is deprecated # if pwd | egrep 'contrib/aix$' then echo "Changing directory to `pwd`/../.." echo "Please run buildbff.sh from your build directory in future." cd ../.. contribaix=1 fi if [ ! -f Makefile ] then echo "Makefile not found (did you run configure?)" exit 1 fi # # Directories used during build: # current dir = $objdir directory you ran ./configure in. # $objdir/$PKGDIR/ directory package files are constructed in # $objdir/$PKGDIR/root/ package root ($FAKE_ROOT) # objdir=`pwd` PKGNAME=openssh PKGDIR=package # # Collect local configuration settings to override defaults # if [ -s ./config.local ] then echo Reading local settings from config.local . ./config.local fi # # Fill in some details from Makefile, like prefix and sysconfdir # the eval also expands variables like sysconfdir=${prefix}/etc # provided they are eval'ed in the correct order # for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir mansubdir sysconfdir piddir srcdir do eval $confvar=`grep "^$confvar=" $objdir/Makefile | cut -d = -f 2` done # # Collect values of privsep user and privsep path # currently only found in config.h # for confvar in SSH_PRIVSEP_USER PRIVSEP_PATH do eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' $objdir/config.h` done # Set privsep defaults if not defined if [ -z "$SSH_PRIVSEP_USER" ] then SSH_PRIVSEP_USER=sshd fi if [ -z "$PRIVSEP_PATH" ] then PRIVSEP_PATH=/var/empty fi # Clean package build directory rm -rf $objdir/$PKGDIR FAKE_ROOT=$objdir/$PKGDIR/root mkdir -p $FAKE_ROOT # Start by faking root install echo "Faking root install..." cd $objdir make install-nokeys DESTDIR=$FAKE_ROOT if [ $? -gt 0 ] then echo "Fake root install failed, stopping." exit 1 fi # # Copy informational files to include in package # cp $srcdir/LICENCE $objdir/$PKGDIR/ cp $srcdir/README* $objdir/$PKGDIR/ # # Extract common info requires for the 'info' part of the package. # AIX requires 4-part version numbers # VERSION=`./ssh -V 2>&1 | cut -f 1 -d , | cut -f 2 -d _` MAJOR=`echo $VERSION | cut -f 1 -d p | cut -f 1 -d .` MINOR=`echo $VERSION | cut -f 1 -d p | cut -f 2 -d .` PATCH=`echo $VERSION | cut -f 1 -d p | cut -f 3 -d .` PORTABLE=`echo $VERSION | awk 'BEGIN{FS="p"}{print $2}'` [ "$PATCH" = "" ] && PATCH=0 [ "$PORTABLE" = "" ] && PORTABLE=0 BFFVERSION=`printf "%d.%d.%d.%d" $MAJOR $MINOR $PATCH $PORTABLE` echo "Building BFF for $PKGNAME $VERSION (package version $BFFVERSION)" # # Set ssh and sshd parameters as per config.local # if [ "${PERMIT_ROOT_LOGIN}" = no ] then perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ $FAKE_ROOT/${sysconfdir}/sshd_config fi if [ "${X11_FORWARDING}" = yes ] then perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ $FAKE_ROOT/${sysconfdir}/sshd_config fi # Rename config files; postinstall script will copy them if necessary for cfgfile in ssh_config sshd_config do mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default done # # Generate lpp control files. # working dir is $FAKE_ROOT but files are generated in dir above # and moved into place just before creation of .bff # cd $FAKE_ROOT echo Generating LPP control files find . ! -name . -print >../openssh.al $inventory >../openssh.inventory cat <../openssh.copyright This software is distributed under a BSD-style license. For the full text of the license, see /usr/lpp/openssh/LICENCE EOD # # openssh.size file allows filesystem expansion as required # generate list of directories containing files # then calculate disk usage for each directory and store in openssh.size # files=`find . -type f -print` dirs=`for file in $files; do dirname $file; done | sort -u` for dir in $dirs do du $dir done > ../openssh.size # # Create postinstall script # cat <>../openssh.post_i #!/bin/sh echo Creating configs from defaults if necessary. for cfgfile in ssh_config sshd_config do if [ ! -f $sysconfdir/\$cfgfile ] then echo "Creating \$cfgfile from default" cp $sysconfdir/\$cfgfile.default $sysconfdir/\$cfgfile else echo "\$cfgfile already exists." fi done echo # Create PrivilegeSeparation user and group if not present echo Checking for PrivilegeSeparation user and group. if cut -f1 -d: /etc/group | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null then echo "PrivSep group $SSH_PRIVSEP_USER already exists." else echo "Creating PrivSep group $SSH_PRIVSEP_USER." mkgroup -A $SSH_PRIVSEP_USER fi # Create user if required if lsuser "$SSH_PRIVSEP_USER" >/dev/null then echo "PrivSep user $SSH_PRIVSEP_USER already exists." else echo "Creating PrivSep user $SSH_PRIVSEP_USER." mkuser gecos='SSHD PrivSep User' login=false rlogin=false account_locked=true pgrp=$SSH_PRIVSEP_USER $SSH_PRIVSEP_USER fi if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' $sysconfdir/sshd_config >/dev/null then echo UsePrivilegeSeparation not enabled, privsep directory not required. else # create chroot directory if required if [ -d $PRIVSEP_PATH ] then echo "PrivSep chroot directory $PRIVSEP_PATH already exists." else echo "Creating PrivSep chroot directory $PRIVSEP_PATH." mkdir $PRIVSEP_PATH chown 0 $PRIVSEP_PATH chgrp 0 $PRIVSEP_PATH chmod 755 $PRIVSEP_PATH fi fi echo # Generate keys unless they already exist echo Creating host keys if required. if [ -f "$sysconfdir/ssh_host_key" ] ; then echo "$sysconfdir/ssh_host_key already exists, skipping." else $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N "" fi if [ -f $sysconfdir/ssh_host_dsa_key ] ; then echo "$sysconfdir/ssh_host_dsa_key already exists, skipping." else $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N "" fi if [ -f $sysconfdir/ssh_host_rsa_key ] ; then echo "$sysconfdir/ssh_host_rsa_key already exists, skipping." else $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N "" fi echo # Set startup command depending on SRC support if [ "$AIX_SRC" = "yes" ] then echo Creating SRC sshd subsystem. rmssys -s sshd 2>&1 >/dev/null mkssys -s sshd -p "$sbindir/sshd" -a '-D' -u 0 -S -n 15 -f 9 -R -G tcpip startupcmd="start $sbindir/sshd \\\"\\\$src_running\\\"" oldstartcmd="$sbindir/sshd" else startupcmd="$sbindir/sshd" oldstartcmd="start $sbindir/sshd \\\"$src_running\\\"" fi # If migrating to or from SRC, change previous startup command # otherwise add to rc.tcpip if egrep "^\$oldstartcmd" /etc/rc.tcpip >/dev/null then if sed "s|^\$oldstartcmd|\$startupcmd|g" /etc/rc.tcpip >/etc/rc.tcpip.new then chmod 0755 /etc/rc.tcpip.new mv /etc/rc.tcpip /etc/rc.tcpip.old && \ mv /etc/rc.tcpip.new /etc/rc.tcpip else echo "Updating /etc/rc.tcpip failed, please check." fi else # Add to system startup if required if grep "^\$startupcmd" /etc/rc.tcpip >/dev/null then echo "sshd found in rc.tcpip, not adding." else echo "Adding sshd to rc.tcpip" echo >>/etc/rc.tcpip echo "# Start sshd" >>/etc/rc.tcpip echo "\$startupcmd" >>/etc/rc.tcpip fi fi EOF # # Create liblpp.a and move control files into it # echo Creating liblpp.a ( cd .. for i in openssh.al openssh.copyright openssh.inventory openssh.post_i openssh.size LICENCE README* do ar -r liblpp.a $i rm $i done ) # # Create lpp_name # # This will end up looking something like: # 4 R I OpenSSH { # OpenSSH 3.0.2.1 1 N U en_US OpenSSH 3.0.2p1 Portable for AIX # [ # % # /usr/local/bin 8073 # /usr/local/etc 189 # /usr/local/libexec 185 # /usr/local/man/man1 145 # /usr/local/man/man8 83 # /usr/local/sbin 2105 # /usr/local/share 3 # % # ] # } echo Creating lpp_name cat <../lpp_name 4 R I $PKGNAME { $PKGNAME $BFFVERSION 1 N U en_US OpenSSH $VERSION Portable for AIX [ % EOF for i in $bindir $sysconfdir $libexecdir $mandir/${mansubdir}1 $mandir/${mansubdir}8 $sbindir $datadir /usr/lpp/openssh do # get size in 512 byte blocks if [ -d $FAKE_ROOT/$i ] then size=`du $FAKE_ROOT/$i | awk '{print $1}'` echo "$i $size" >>../lpp_name fi done echo '%' >>../lpp_name echo ']' >>../lpp_name echo '}' >>../lpp_name # # Move pieces into place # mkdir -p usr/lpp/openssh mv ../liblpp.a usr/lpp/openssh mv ../lpp_name . # # Now invoke backup to create .bff file # note: lpp_name needs to be the first file so we generate the # file list on the fly and feed it to backup using -i # echo Creating $PKGNAME-$VERSION.bff with backup... rm -f $PKGNAME-$VERSION.bff ( echo "./lpp_name" find . ! -name lpp_name -a ! -name . -print ) | backup -i -q -f ../$PKGNAME-$VERSION.bff $filelist # # Move package into final location and clean up # mv ../$PKGNAME-$VERSION.bff $startdir cd $startdir rm -rf $objdir/$PKGDIR echo $0: done. openssh-7.2p2/contrib/aix/inventory.sh010075500017500001750000000031251267006270000162700ustar00djmdjm#!/bin/sh # # inventory.sh # $Id: inventory.sh,v 1.6 2003/11/21 12:48:56 djm Exp $ # # Originally written by Ben Lindstrom, modified by Darren Tucker to use perl # This file is placed into the public domain. # # This will produce an AIX package inventory file, which looks like: # # /usr/local/bin: # class=apply,inventory,openssh # owner=root # group=system # mode=755 # type=DIRECTORY # /usr/local/bin/slogin: # class=apply,inventory,openssh # owner=root # group=system # mode=777 # type=SYMLINK # target=ssh # /usr/local/share/Ssh.bin: # class=apply,inventory,openssh # owner=root # group=system # mode=644 # type=FILE # size=VOLATILE # checksum=VOLATILE find . ! -name . -print | perl -ne '{ chomp; if ( -l $_ ) { ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=lstat; } else { ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=stat; } # Start to display inventory information $name = $_; $name =~ s|^.||; # Strip leading dot from path print "$name:\n"; print "\tclass=apply,inventory,openssh\n"; print "\towner=root\n"; print "\tgroup=system\n"; printf "\tmode=%lo\n", $mod & 07777; # Mask perm bits if ( -l $_ ) { # Entry is SymLink print "\ttype=SYMLINK\n"; printf "\ttarget=%s\n", readlink($_); } elsif ( -f $_ ) { # Entry is File print "\ttype=FILE\n"; print "\tsize=$sz\n"; print "\tchecksum=VOLATILE\n"; } elsif ( -d $_ ) { # Entry is Directory print "\ttype=DIRECTORY\n"; } }' openssh-7.2p2/contrib/aix/pam.conf010064400017500001750000000012741267006270000153230ustar00djmdjm# # PAM configuration file /etc/pam.conf # Example for OpenSSH on AIX 5.2 # # Authentication Management sshd auth required /usr/lib/security/pam_aix OTHER auth required /usr/lib/security/pam_aix # Account Management sshd account required /usr/lib/security/pam_aix OTHER account required /usr/lib/security/pam_aix # Password Management sshd password required /usr/lib/security/pam_aix OTHER password required /usr/lib/security/pam_aix # Session Management sshd session required /usr/lib/security/pam_aix OTHER session required /usr/lib/security/pam_aix openssh-7.2p2/contrib/cygwin004075500017500001750000000000001267006270000143365ustar00djmdjmopenssh-7.2p2/contrib/cygwin/Makefile010064400017500001750000000061051267006270000160540ustar00djmdjmsrcdir=../.. copyidsrcdir=.. prefix=/usr exec_prefix=$(prefix) bindir=$(prefix)/bin datadir=$(prefix)/share mandir=$(datadir)/man docdir=$(datadir)/doc sshdocdir=$(docdir)/openssh cygdocdir=$(docdir)/Cygwin sysconfdir=/etc defaultsdir=$(sysconfdir)/defaults/etc inetdefdir=$(defaultsdir)/inetd.d PRIVSEP_PATH=/var/empty INSTALL=/usr/bin/install -c DESTDIR= all: @echo @echo "Use \`make cygwin-postinstall DESTDIR=[package directory]'" @echo "Be sure having DESTDIR set correctly!" @echo move-config-files: $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(sysconfdir)/sshd_config $(srcdir)/mkinstalldirs $(DESTDIR)$(defaultsdir) mv $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(defaultsdir) mv $(DESTDIR)$(sysconfdir)/sshd_config $(DESTDIR)$(defaultsdir) remove-empty-dir: rm -rf $(DESTDIR)$(PRIVSEP_PATH) install-inetd-config: $(srcdir)/mkinstalldirs $(DESTDIR)$(inetdefdir) $(INSTALL) -m 644 sshd-inetd $(DESTDIR)$(inetdefdir)/sshd-inetd install-sshdoc: $(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir) -$(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS -$(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(sshdocdir)/ChangeLog -$(INSTALL) -m 644 $(srcdir)/LICENCE $(DESTDIR)$(sshdocdir)/LICENCE -$(INSTALL) -m 644 $(srcdir)/OVERVIEW $(DESTDIR)$(sshdocdir)/OVERVIEW -$(INSTALL) -m 644 $(srcdir)/PROTOCOL $(DESTDIR)$(sshdocdir)/PROTOCOL -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.agent $(DESTDIR)$(sshdocdir)/PROTOCOL.agent -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.certkeys $(DESTDIR)$(sshdocdir)/PROTOCOL.certkeys -$(INSTALL) -m 644 $(srcdir)/PROTOCOL.mux $(DESTDIR)$(sshdocdir)/PROTOCOL.mux -$(INSTALL) -m 644 $(srcdir)/README $(DESTDIR)$(sshdocdir)/README -$(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns -$(INSTALL) -m 644 $(srcdir)/README.platform $(DESTDIR)$(sshdocdir)/README.platform -$(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep -$(INSTALL) -m 644 $(srcdir)/README.tun $(DESTDIR)$(sshdocdir)/README.tun -$(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO install-cygwindoc: README $(srcdir)/mkinstalldirs $(DESTDIR)$(cygdocdir) $(INSTALL) -m 644 README $(DESTDIR)$(cygdocdir)/openssh.README install-doc: install-sshdoc install-cygwindoc install-scripts: ssh-host-config ssh-user-config $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config $(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config install-copy-id: $(copyidsrcdir)/ssh-copy-id $(copyidsrcdir)/ssh-copy-id.1 $(INSTALL) -m 755 $(copyidsrcdir)/ssh-copy-id $(DESTDIR)$(bindir)/ssh-copy-id $(INSTALL) -m 644 $(copyidsrcdir)/ssh-copy-id.1 $(DESTDIR)$(mandir)/man1/ssh-copy-id.1 gzip-man-pages: rm $(DESTDIR)$(mandir)/man1/slogin.1 gzip $(DESTDIR)$(mandir)/man1/*.1 gzip $(DESTDIR)$(mandir)/man5/*.5 gzip $(DESTDIR)$(mandir)/man8/*.8 cd $(DESTDIR)$(mandir)/man1 && ln -s ssh.1.gz slogin.1.gz cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts install-copy-id gzip-man-pages @echo "Cygwin specific configuration finished." openssh-7.2p2/contrib/cygwin/README010064400017500001750000000057221267006270000153000ustar00djmdjmThis package describes important Cygwin specific stuff concerning OpenSSH. The binary package is usually built for recent Cygwin versions and might not run on older versions. Please check http://cygwin.com/ for information about current Cygwin releases. ================== Host configuration ================== If you are installing OpenSSH the first time, you can generate global config files and server keys, as well as installing sshd as a service, by running /usr/bin/ssh-host-config Note that this binary archive doesn't contain default config files in /etc. That files are only created if ssh-host-config is started. To support testing and unattended installation ssh-host-config got some options: usage: ssh-host-config [OPTION]... Options: --debug -d Enable shell's debug output. --yes -y Answer all questions with "yes" automatically. --no -n Answer all questions with "no" automatically. --cygwin -c Use "options" as value for CYGWIN environment var. --port -p sshd listens on port n. --user -u privileged user for service, default 'cyg_server'. --pwd -w Use "pwd" as password for privileged user. --privileged On Windows XP, require privileged user instead of LocalSystem for sshd service. Installing sshd as daemon via ssh-host-config is recommended. Alternatively you can start sshd via inetd, if you have the inetutils package installed. Just run ssh-host-config, but answer "no" when asked to install sshd as service. The ssh-host-config script also adds the required lines to /etc/inetd.conf and /etc/services. ================== User configuration ================== Any user can simplify creating the own private and public keys by running /usr/bin/ssh-user-config To support testing and unattended installation ssh-user-config got some options as well: usage: ssh-user-config [OPTION]... Options: --debug -d Enable shell's debug output. --yes -y Answer all questions with "yes" automatically. --no -n Answer all questions with "no" automatically. --passphrase -p word Use "word" as passphrase automatically. Please note that OpenSSH does never use the value of $HOME to search for the users configuration files! It always uses the value of the pw_dir field in /etc/passwd as the home directory. If no home diretory is set in /etc/passwd, the root directory is used instead! ================ Building OpenSSH ================ Building from source is easy. Just unpack the source archive, cd to that directory, and call cygport: cygport openssh.cygport all You must have installed the following packages to be able to build OpenSSH with the aforementioned cygport script: zlib crypt openssl-devel libedit-devel libkrb5-devel Please send requests, error reports etc. to cygwin@cygwin.com. Have fun, Corinna Vinschen Cygwin Developer Red Hat Inc. openssh-7.2p2/contrib/cygwin/ssh-host-config010064400017500001750000000555421267006270000173630ustar00djmdjm#!/bin/bash # # ssh-host-config, Copyright 2000-2014 Red Hat Inc. # # This file is part of the Cygwin port of OpenSSH. # # 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", 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. # ====================================================================== # Initialization # ====================================================================== CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh # List of apps used. This is checkad for existance in csih_sanity_check # Don't use *any* transient commands before sourcing the csih helper script, # otherwise the sanity checks are short-circuited. declare -a csih_required_commands=( /usr/bin/basename coreutils /usr/bin/cat coreutils /usr/bin/chmod coreutils /usr/bin/dirname coreutils /usr/bin/id coreutils /usr/bin/mv coreutils /usr/bin/rm coreutils /usr/bin/cygpath cygwin /usr/bin/mkpasswd cygwin /usr/bin/mount cygwin /usr/bin/ps cygwin /usr/bin/umount cygwin /usr/bin/cmp diffutils /usr/bin/grep grep /usr/bin/awk gawk /usr/bin/ssh-keygen openssh /usr/sbin/sshd openssh /usr/bin/sed sed ) csih_sanity_check_server=yes source ${CSIH_SCRIPT} PROGNAME=$(/usr/bin/basename $0) _tdir=$(/usr/bin/dirname $0) PROGDIR=$(cd $_tdir && pwd) # Subdirectory where the new package is being installed PREFIX=/usr # Directory where the config files are stored SYSCONFDIR=/etc LOCALSTATEDIR=/var sshd_config_configured=no port_number=22 service_name=sshd strictmodes=yes privsep_used=yes cygwin_value="" user_account= password_value= opt_force=no # ====================================================================== # Routine: update_services_file # ====================================================================== update_services_file() { local _my_etcdir="/ssh-host-config.$$" local _win_etcdir local _services local _spaces local _serv_tmp local _wservices local ret=0 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc" _services="${_my_etcdir}/services" _spaces=" #" _serv_tmp="${_my_etcdir}/srv.out.$$" /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}" # Depends on the above mount _wservices=`cygpath -w "${_services}"` # Add ssh 22/tcp and ssh 22/udp to services if [ `/usr/bin/grep -q 'ssh[[:space:]][[:space:]]*22' "${_services}"; echo $?` -ne 0 ] then if /usr/bin/awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" then if /usr/bin/mv "${_serv_tmp}" "${_services}" then csih_inform "Added ssh to ${_wservices}" else csih_warning "Adding ssh to ${_wservices} failed!" let ++ret fi /usr/bin/rm -f "${_serv_tmp}" else csih_warning "Adding ssh to ${_wservices} failed!" let ++ret fi fi /usr/bin/umount "${_my_etcdir}" return $ret } # --- End of update_services_file --- # # ====================================================================== # Routine: sshd_strictmodes # MODIFIES: strictmodes # ====================================================================== sshd_strictmodes() { if [ "${sshd_config_configured}" != "yes" ] then echo csih_inform "StrictModes is set to 'yes' by default." csih_inform "This is the recommended setting, but it requires that the POSIX" csih_inform "permissions of the user's home directory, the user's .ssh" csih_inform "directory, and the user's ssh key files are tight so that" csih_inform "only the user has write permissions." csih_inform "On the other hand, StrictModes don't work well with default" csih_inform "Windows permissions of a home directory mounted with the" csih_inform "'noacl' option, and they don't work at all if the home" csih_inform "directory is on a FAT or FAT32 partition." if ! csih_request "Should StrictModes be used?" then strictmodes=no fi fi return 0 } # ====================================================================== # Routine: sshd_privsep # MODIFIES: privsep_used # ====================================================================== sshd_privsep() { local ret=0 if [ "${sshd_config_configured}" != "yes" ] then echo csih_inform "Privilege separation is set to 'sandbox' by default since" csih_inform "OpenSSH 6.1. This is unsupported by Cygwin and has to be set" csih_inform "to 'yes' or 'no'." csih_inform "However, using privilege separation requires a non-privileged account" csih_inform "called 'sshd'." csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep." if csih_request "Should privilege separation be used?" then privsep_used=yes if ! csih_create_unprivileged_user sshd then csih_error_recoverable "Couldn't create user 'sshd'!" csih_error_recoverable "Privilege separation set to 'no' again!" csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!" let ++ret privsep_used=no fi else privsep_used=no fi fi return $ret } # --- End of sshd_privsep --- # # ====================================================================== # Routine: sshd_config_tweak # ====================================================================== sshd_config_tweak() { local ret=0 # Modify sshd_config csih_inform "Updating ${SYSCONFDIR}/sshd_config file" if [ "${port_number}" -ne 22 ] then /usr/bin/sed -i -e "s/^#\?[[:space:]]*Port[[:space:]].*/Port ${port_number}/" \ ${SYSCONFDIR}/sshd_config if [ $? -ne 0 ] then csih_warning "Setting listening port to ${port_number} failed!" csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" let ++ret fi fi if [ "${strictmodes}" = "no" ] then /usr/bin/sed -i -e "s/^#\?[[:space:]]*StrictModes[[:space:]].*/StrictModes no/" \ ${SYSCONFDIR}/sshd_config if [ $? -ne 0 ] then csih_warning "Setting StrictModes to 'no' failed!" csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" let ++ret fi fi if [ "${sshd_config_configured}" != "yes" ] then /usr/bin/sed -i -e " s/^#\?UsePrivilegeSeparation .*/UsePrivilegeSeparation ${privsep_used}/" \ ${SYSCONFDIR}/sshd_config if [ $? -ne 0 ] then csih_warning "Setting privilege separation failed!" csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" let ++ret fi fi return $ret } # --- End of sshd_config_tweak --- # # ====================================================================== # Routine: update_inetd_conf # ====================================================================== update_inetd_conf() { local _inetcnf="${SYSCONFDIR}/inetd.conf" local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$" local _inetcnf_dir="${SYSCONFDIR}/inetd.d" local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd" local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$" local _with_comment=1 local ret=0 if [ -d "${_inetcnf_dir}" ] then # we have inetutils-1.5 inetd.d support if [ -f "${_inetcnf}" ] then /usr/bin/grep -q '^[[:space:]]*ssh' "${_inetcnf}" && _with_comment=0 # check for sshd OR ssh in top-level inetd.conf file, and remove # will be replaced by a file in inetd.d/ if [ $(/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?) -eq 0 ] then /usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" if [ -f "${_inetcnf_tmp}" ] then if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" then csih_inform "Removed ssh[d] from ${_inetcnf}" else csih_warning "Removing ssh[d] from ${_inetcnf} failed!" let ++ret fi /usr/bin/rm -f "${_inetcnf_tmp}" else csih_warning "Removing ssh[d] from ${_inetcnf} failed!" let ++ret fi fi fi csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults" if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1 then if [ "${_with_comment}" -eq 0 ] then /usr/bin/sed -e 's/@COMMENT@[[:space:]]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" else /usr/bin/sed -e 's/@COMMENT@[[:space:]]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" fi if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}" then csih_inform "Updated ${_sshd_inetd_conf}" else csih_warning "Updating ${_sshd_inetd_conf} failed!" let ++ret fi fi elif [ -f "${_inetcnf}" ] then /usr/bin/grep -q '^[[:space:]]*sshd' "${_inetcnf}" && _with_comment=0 # check for sshd in top-level inetd.conf file, and remove # will be replaced by a file in inetd.d/ if [ `/usr/bin/grep -q '^#\?[[:space:]]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] then /usr/bin/grep -v '^#\?[[:space:]]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" if [ -f "${_inetcnf_tmp}" ] then if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" then csih_inform "Removed sshd from ${_inetcnf}" else csih_warning "Removing sshd from ${_inetcnf} failed!" let ++ret fi /usr/bin/rm -f "${_inetcnf_tmp}" else csih_warning "Removing sshd from ${_inetcnf} failed!" let ++ret fi fi # Add ssh line to inetd.conf if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] then if [ "${_with_comment}" -eq 0 ] then echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" else echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" fi if [ $? -eq 0 ] then csih_inform "Added ssh to ${_inetcnf}" else csih_warning "Adding ssh to ${_inetcnf} failed!" let ++ret fi fi fi return $ret } # --- End of update_inetd_conf --- # # ====================================================================== # Routine: check_service_files_ownership # Checks that the files in /etc and /var belong to the right owner # ====================================================================== check_service_files_ownership() { local run_service_as=$1 local ret=0 if [ -z "${run_service_as}" ] then accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | /usr/bin/sed -ne 's/^Account *: *//gp') if [ "${accnt_name}" = "LocalSystem" ] then # Convert "LocalSystem" to "SYSTEM" as is the correct account name run_service_as="SYSTEM" else dom="${accnt_name%%\\*}" accnt_name="${accnt_name#*\\}" if [ "${dom}" = '.' ] then # Check local account run_service_as=$(/usr/bin/mkpasswd -l -u "${accnt_name}" | /usr/bin/awk -F: '{print $1;}') else # Check domain run_service_as=$(/usr/bin/mkpasswd -d "${dom}" -u "${accnt_name}" | /usr/bin/awk -F: '{print $1;}') fi fi if [ -z "${run_service_as}" ] then csih_warning "Couldn't determine name of user running sshd service from account database!" csih_warning "As a result, this script cannot make sure that the files used" csih_warning "by the sshd service belong to the user running the service." return 1 fi fi for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub do if [ -f "$i" ] then if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1 then csih_warning "Couldn't change owner of $i!" let ++ret fi fi done if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1 then csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!" let ++ret fi if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 then csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!" let ++ret fi if [ -f ${LOCALSTATEDIR}/log/sshd.log ] then if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1 then csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!" let ++ret fi fi if [ $ret -ne 0 ] then csih_warning "Couldn't change owner of important files to ${run_service_as}!" csih_warning "This may cause the sshd service to fail! Please make sure that" csih_warning "you have suufficient permissions to change the ownership of files" csih_warning "and try to run the ssh-host-config script again." fi return $ret } # --- End of check_service_files_ownership --- # # ====================================================================== # Routine: install_service # Install sshd as a service # ====================================================================== install_service() { local run_service_as local password local ret=0 echo if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 then csih_inform "Sshd service is already installed." check_service_files_ownership "" || let ret+=$? else echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?" if csih_request "(Say \"no\" if it is already installed as a service)" then csih_get_cygenv "${cygwin_value}" if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) then csih_inform "On Windows Server 2003, Windows Vista, and above, the" csih_inform "SYSTEM account cannot setuid to other users -- a capability" csih_inform "sshd requires. You need to have or to create a privileged" csih_inform "account. This script will help you do so." echo [ "${opt_force}" = "yes" ] && opt_f=-f [ -n "${user_account}" ] && opt_u="-u ""${user_account}""" csih_select_privileged_username ${opt_f} ${opt_u} sshd if ! csih_create_privileged_user "${password_value}" then csih_error_recoverable "There was a serious problem creating a privileged user." csih_request "Do you want to proceed anyway?" || exit 1 let ++ret fi fi # Never returns empty if NT or above run_service_as=$(csih_service_should_run_as) if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] then password="${csih_PRIVILEGED_PASSWORD}" if [ -z "${password}" ] then csih_get_value "Please enter the password for user '${run_service_as}':" "-s" password="${csih_value}" fi fi # At this point, we either have $run_service_as = "system" and # $password is empty, or $run_service_as is some privileged user and # (hopefully) $password contains the correct password. So, from here # out, we use '-z "${password}"' to discriminate the two cases. csih_check_user "${run_service_as}" if [ -n "${csih_cygenv}" ] then cygwin_env=( -e "CYGWIN=${csih_cygenv}" ) fi if [ -z "${password}" ] then if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ -a "-D" -y tcpip "${cygwin_env[@]}" then echo csih_inform "The sshd service has been installed under the LocalSystem" csih_inform "account (also known as SYSTEM). To start the service now, call" csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it" csih_inform "will start automatically after the next reboot." fi else if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ -a "-D" -y tcpip "${cygwin_env[@]}" \ -u "${run_service_as}" -w "${password}" then /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight echo csih_inform "The sshd service has been installed under the '${run_service_as}'" csih_inform "account. To start the service now, call \`net start ${service_name}' or" csih_inform "\`cygrunsrv -S ${service_name}'. Otherwise, it will start automatically" csih_inform "after the next reboot." fi fi if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 then check_service_files_ownership "${run_service_as}" || let ret+=$? else csih_error_recoverable "Installing sshd as a service failed!" let ++ret fi fi # user allowed us to install as service fi # service not yet installed return $ret } # --- End of install_service --- # # ====================================================================== # Main Entry Point # ====================================================================== # Check how the script has been started. If # (1) it has been started by giving the full path and # that path is /etc/postinstall, OR # (2) Otherwise, if the environment variable # SSH_HOST_CONFIG_AUTO_ANSWER_NO is set # then set auto_answer to "no". This allows automatic # creation of the config files in /etc w/o overwriting # them if they already exist. In both cases, color # escape sequences are suppressed, so as to prevent # cluttering setup's logfiles. if [ "$PROGDIR" = "/etc/postinstall" ] then csih_auto_answer="no" csih_disable_color opt_force=yes fi if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ] then csih_auto_answer="no" csih_disable_color opt_force=yes fi # ====================================================================== # Parse options # ====================================================================== while : do case $# in 0) break ;; esac option=$1 shift case "${option}" in -d | --debug ) set -x csih_trace_on ;; -y | --yes ) csih_auto_answer=yes opt_force=yes ;; -n | --no ) csih_auto_answer=no opt_force=yes ;; -c | --cygwin ) cygwin_value="$1" shift ;; -N | --name ) service_name=$1 shift ;; -p | --port ) port_number=$1 shift ;; -u | --user ) user_account="$1" shift ;; -w | --pwd ) password_value="$1" shift ;; --privileged ) csih_FORCE_PRIVILEGED_USER=yes ;; *) echo "usage: ${progname} [OPTION]..." echo echo "This script creates an OpenSSH host configuration." echo echo "Options:" echo " --debug -d Enable shell's debug output." echo " --yes -y Answer all questions with \"yes\" automatically." echo " --no -n Answer all questions with \"no\" automatically." echo " --cygwin -c Use \"options\" as value for CYGWIN environment var." echo " --name -N sshd windows service name." echo " --port -p sshd listens on port n." echo " --user -u privileged user for service, default 'cyg_server'." echo " --pwd -w Use \"pwd\" as password for privileged user." echo " --privileged On Windows XP, require privileged user" echo " instead of LocalSystem for sshd service." echo exit 1 ;; esac done # ====================================================================== # Action! # ====================================================================== # Check for running ssh/sshd processes first. Refuse to do anything while # some ssh processes are still running if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$' then echo csih_error "There are still ssh processes running. Please shut them down first." fi # Make sure the user is running in an administrative context admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no) if [ "${admin}" != "yes" ] then echo csih_warning "Running this script typically requires administrator privileges!" csih_warning "However, it seems your account does not have these privileges." csih_warning "Here's the list of groups in your user token:" echo /usr/bin/id -Gnz | xargs -0n1 echo " " echo csih_warning "This usually means you're running this script from a non-admin" csih_warning "desktop session, or in a non-elevated shell under UAC control." echo csih_warning "Make sure you have the appropriate privileges right now," csih_warning "otherwise parts of this script will probably fail!" echo echo -e "${_csih_QUERY_STR} Are you sure you want to continue? (Say \"no\" if you're not sure" if ! csih_request "you have the required privileges)" then echo csih_inform "Ok. Exiting. Make sure to switch to an administrative account" csih_inform "or to start this script from an elevated shell." exit 1 fi fi echo warning_cnt=0 # Create /var/log/lastlog if not already exists if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] then echo csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \ "Cannot create ssh host configuration." fi if [ ! -e ${LOCALSTATEDIR}/log/lastlog ] then /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 then csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!" let ++warning_cnt fi fi # Create /var/empty file used as chroot jail for privilege separation csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory." if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1 then csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!" let ++warning_cnt fi # generate missing host keys csih_inform "Generating missing SSH host keys" /usr/bin/ssh-keygen -A || let warning_cnt+=$? # handle ssh_config csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1 then if [ "${port_number}" != "22" ] then csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port" echo "Host localhost" >> ${SYSCONFDIR}/ssh_config echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config fi fi # handle sshd_config (and privsep) csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 then sshd_config_configured=yes fi sshd_strictmodes || let warning_cnt+=$? sshd_privsep || let warning_cnt+=$? sshd_config_tweak || let warning_cnt+=$? update_services_file || let warning_cnt+=$? update_inetd_conf || let warning_cnt+=$? install_service || let warning_cnt+=$? echo if [ $warning_cnt -eq 0 ] then csih_inform "Host configuration finished. Have fun!" else csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!" csih_warning "Make sure that all problems reported are fixed," csih_warning "then re-run ssh-host-config." fi exit $warning_cnt openssh-7.2p2/contrib/cygwin/ssh-user-config010064400017500001750000000177411267006270000173630ustar00djmdjm#!/bin/bash # # ssh-user-config, Copyright 2000-2014 Red Hat Inc. # # This file is part of the Cygwin port of OpenSSH. # # 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", 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. # ====================================================================== # Initialization # ====================================================================== PROGNAME=$(basename -- $0) _tdir=$(dirname -- $0) PROGDIR=$(cd $_tdir && pwd) CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh # Subdirectory where the new package is being installed PREFIX=/usr # Directory where the config files are stored SYSCONFDIR=/etc source ${CSIH_SCRIPT} auto_passphrase="no" passphrase="" pwdhome= with_passphrase= # ====================================================================== # Routine: create_identity # optionally create identity of type argument in ~/.ssh # optionally add result to ~/.ssh/authorized_keys # ====================================================================== create_identity() { local file="$1" local type="$2" local name="$3" if [ ! -f "${pwdhome}/.ssh/${file}" ] then if csih_request "Shall I create a ${name} identity file for you?" then csih_inform "Generating ${pwdhome}/.ssh/${file}" if [ "${with_passphrase}" = "yes" ] then ssh-keygen -t "${type}" -N "${passphrase}" -f "${pwdhome}/.ssh/${file}" > /dev/null else ssh-keygen -t "${type}" -f "${pwdhome}/.ssh/${file}" > /dev/null fi if csih_request "Do you want to use this identity to login to this machine?" then csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys" cat "${pwdhome}/.ssh/${file}.pub" >> "${pwdhome}/.ssh/authorized_keys" fi fi fi } # === End of create_ssh1_identity() === # readonly -f create_identity # ====================================================================== # Routine: check_user_homedir # Perform various checks on the user's home directory # SETS GLOBAL VARIABLE: # pwdhome # ====================================================================== check_user_homedir() { pwdhome=$(getent passwd $UID | awk -F: '{ print $6; }') if [ "X${pwdhome}" = "X" ] then csih_error_multi \ "There is no home directory set for you in the account database." \ 'Setting $HOME is not sufficient!' fi if [ ! -d "${pwdhome}" ] then csih_error_multi \ "${pwdhome} is set in the account database as your home directory" \ 'but it is not a valid directory. Cannot create user identity files.' fi # If home is the root dir, set home to empty string to avoid error messages # in subsequent parts of that script. if [ "X${pwdhome}" = "X/" ] then # But first raise a warning! csih_warning "Your home directory in the account database is set to root (/). This is not recommended!" if csih_request "Would you like to proceed anyway?" then pwdhome='' else csih_warning "Exiting. Configuration is not complete" exit 1 fi fi if [ -d "${pwdhome}" -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ] then echo csih_warning 'group and other have been revoked write permission to your home' csih_warning "directory ${pwdhome}." csih_warning 'This is required by OpenSSH to allow public key authentication using' csih_warning 'the key files stored in your .ssh subdirectory.' csih_warning 'Revert this change ONLY if you know what you are doing!' echo fi } # === End of check_user_homedir() === # readonly -f check_user_homedir # ====================================================================== # Routine: check_user_dot_ssh_dir # Perform various checks on the ~/.ssh directory # PREREQUISITE: # pwdhome -- check_user_homedir() # ====================================================================== check_user_dot_ssh_dir() { if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ] then csih_error "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files." fi if [ ! -e "${pwdhome}/.ssh" ] then mkdir "${pwdhome}/.ssh" if [ ! -e "${pwdhome}/.ssh" ] then csih_error "Creating users ${pwdhome}/.ssh directory failed" fi fi } # === End of check_user_dot_ssh_dir() === # readonly -f check_user_dot_ssh_dir # ====================================================================== # Routine: fix_authorized_keys_perms # Corrects the permissions of ~/.ssh/authorized_keys # PREREQUISITE: # pwdhome -- check_user_homedir() # ====================================================================== fix_authorized_keys_perms() { if [ -e "${pwdhome}/.ssh/authorized_keys" ] then setfacl -b "${pwdhome}/.ssh/authorized_keys" 2>/dev/null || echo -n if ! chmod u-x,g-wx,o-wx "${pwdhome}/.ssh/authorized_keys" then csih_warning "Setting correct permissions to ${pwdhome}/.ssh/authorized_keys" csih_warning "failed. Please care for the correct permissions. The minimum requirement" csih_warning "is, the owner needs read permissions." echo fi fi } # === End of fix_authorized_keys_perms() === # readonly -f fix_authorized_keys_perms # ====================================================================== # Main Entry Point # ====================================================================== # Check how the script has been started. If # (1) it has been started by giving the full path and # that path is /etc/postinstall, OR # (2) Otherwise, if the environment variable # SSH_USER_CONFIG_AUTO_ANSWER_NO is set # then set auto_answer to "no". This allows automatic # creation of the config files in /etc w/o overwriting # them if they already exist. In both cases, color # escape sequences are suppressed, so as to prevent # cluttering setup's logfiles. if [ "$PROGDIR" = "/etc/postinstall" ] then csih_auto_answer="no" csih_disable_color fi if [ -n "${SSH_USER_CONFIG_AUTO_ANSWER_NO}" ] then csih_auto_answer="no" csih_disable_color fi # ====================================================================== # Parse options # ====================================================================== while : do case $# in 0) break ;; esac option=$1 shift case "$option" in -d | --debug ) set -x csih_trace_on ;; -y | --yes ) csih_auto_answer=yes ;; -n | --no ) csih_auto_answer=no ;; -p | --passphrase ) with_passphrase="yes" passphrase=$1 shift ;; *) echo "usage: ${PROGNAME} [OPTION]..." echo echo "This script creates an OpenSSH user configuration." echo echo "Options:" echo " --debug -d Enable shell's debug output." echo " --yes -y Answer all questions with \"yes\" automatically." echo " --no -n Answer all questions with \"no\" automatically." echo " --passphrase -p word Use \"word\" as passphrase automatically." echo exit 1 ;; esac done # ====================================================================== # Action! # ====================================================================== check_user_homedir check_user_dot_ssh_dir create_identity id_rsa rsa "SSH2 RSA" create_identity id_dsa dsa "SSH2 DSA" create_identity id_ecdsa ecdsa "SSH2 ECDSA" create_identity identity rsa1 "(deprecated) SSH1 RSA" fix_authorized_keys_perms echo csih_inform "Configuration finished. Have fun!" openssh-7.2p2/contrib/cygwin/sshd-inetd010064400017500001750000000003001267006270000163700ustar00djmdjm# This file can be used to enable sshd as a slave of the inetd service # To do so, the line below should be uncommented. @COMMENT@ ssh stream tcp nowait root /usr/sbin/sshd sshd -i openssh-7.2p2/contrib/findssl.sh010064400017500001750000000113711267006270000151130ustar00djmdjm#!/bin/sh # # $Id: findssl.sh,v 1.4 2007/02/19 11:44:25 dtucker Exp $ # # findssl.sh # Search for all instances of OpenSSL headers and libraries # and print their versions. # Intended to help diagnose OpenSSH's "OpenSSL headers do not # match your library" errors. # # Written by Darren Tucker (dtucker at zip dot com dot au) # This file is placed in the public domain. # # Release history: # 2002-07-27: Initial release. # 2002-08-04: Added public domain notice. # 2003-06-24: Incorporated readme, set library paths. First cvs version. # 2004-12-13: Add traps to cleanup temp files, from Amarendra Godbole. # # "OpenSSL headers do not match your library" are usually caused by # OpenSSH's configure picking up an older version of OpenSSL headers # or libraries. You can use the following # procedure to help identify # the cause. # # The output of configure will tell you the versions of the OpenSSL # headers and libraries that were picked up, for example: # # checking OpenSSL header version... 90604f (OpenSSL 0.9.6d 9 May 2002) # checking OpenSSL library version... 90602f (OpenSSL 0.9.6b [engine] 9 Jul 2001) # checking whether OpenSSL's headers match the library... no # configure: error: Your OpenSSL headers do not match your library # # Now run findssl.sh. This should identify the headers and libraries # present and their versions. You should be able to identify the # libraries and headers used and adjust your CFLAGS or remove incorrect # versions. The output will show OpenSSL's internal version identifier # and should look something like: # $ ./findssl.sh # Searching for OpenSSL header files. # 0x0090604fL /usr/include/openssl/opensslv.h # 0x0090604fL /usr/local/ssl/include/openssl/opensslv.h # # Searching for OpenSSL shared library files. # 0x0090602fL /lib/libcrypto.so.0.9.6b # 0x0090602fL /lib/libcrypto.so.2 # 0x0090581fL /usr/lib/libcrypto.so.0 # 0x0090602fL /usr/lib/libcrypto.so # 0x0090581fL /usr/lib/libcrypto.so.0.9.5a # 0x0090600fL /usr/lib/libcrypto.so.0.9.6 # 0x0090600fL /usr/lib/libcrypto.so.1 # # Searching for OpenSSL static library files. # 0x0090602fL /usr/lib/libcrypto.a # 0x0090604fL /usr/local/ssl/lib/libcrypto.a # # In this example, I gave configure no extra flags, so it's picking up # the OpenSSL header from /usr/include/openssl (90604f) and the library # from /usr/lib/ (90602f). # # Adjust these to suit your compiler. # You may also need to set the *LIB*PATH environment variables if # DEFAULT_LIBPATH is not correct for your system. # CC=gcc STATIC=-static # # Cleanup on interrupt # trap 'rm -f conftest.c' INT HUP TERM # # Set up conftest C source # rm -f findssl.log cat >conftest.c < int main(){printf("0x%08xL\n", SSLeay());} EOD # # Set default library paths if not already set # DEFAULT_LIBPATH=/usr/lib:/usr/local/lib LIBPATH=${LIBPATH:=$DEFAULT_LIBPATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH:=$DEFAULT_LIBPATH} LIBRARY_PATH=${LIBRARY_PATH:=$DEFAULT_LIBPATH} export LIBPATH LD_LIBRARY_PATH LIBRARY_PATH # not all platforms have a 'which' command if which ls >/dev/null 2>/dev/null; then : which is defined else which () { saveIFS="$IFS" IFS=: for p in $PATH; do if test -x "$p/$1" -a -f "$p/$1"; then IFS="$saveIFS" echo "$p/$1" return 0 fi done IFS="$saveIFS" return 1 } fi # # Search for OpenSSL headers and print versions # echo Searching for OpenSSL header files. if [ -x "`which locate`" ] then headers=`locate opensslv.h` else headers=`find / -name opensslv.h -print 2>/dev/null` fi for header in $headers do ver=`awk '/OPENSSL_VERSION_NUMBER/{printf \$3}' $header` echo "$ver $header" done echo # # Search for shared libraries. # Relies on shared libraries looking like "libcrypto.s*" # echo Searching for OpenSSL shared library files. if [ -x "`which locate`" ] then libraries=`locate libcrypto.s` else libraries=`find / -name 'libcrypto.s*' -print 2>/dev/null` fi for lib in $libraries do (echo "Trying libcrypto $lib" >>findssl.log dir=`dirname $lib` LIBPATH="$dir:$LIBPATH" LD_LIBRARY_PATH="$dir:$LIBPATH" LIBRARY_PATH="$dir:$LIBPATH" export LIBPATH LD_LIBRARY_PATH LIBRARY_PATH ${CC} -o conftest conftest.c $lib 2>>findssl.log if [ -x ./conftest ] then ver=`./conftest 2>/dev/null` rm -f ./conftest echo "$ver $lib" fi) done echo # # Search for static OpenSSL libraries and print versions # echo Searching for OpenSSL static library files. if [ -x "`which locate`" ] then libraries=`locate libcrypto.a` else libraries=`find / -name libcrypto.a -print 2>/dev/null` fi for lib in $libraries do libdir=`dirname $lib` echo "Trying libcrypto $lib" >>findssl.log ${CC} ${STATIC} -o conftest conftest.c -L${libdir} -lcrypto 2>>findssl.log if [ -x ./conftest ] then ver=`./conftest 2>/dev/null` rm -f ./conftest echo "$ver $lib" fi done # # Clean up # rm -f conftest.c openssh-7.2p2/contrib/gnome-ssh-askpass1.c010064400017500001750000000125401267006270000167040ustar00djmdjm/* * Copyright (c) 2000-2002 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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. */ /* * This is a simple GNOME SSH passphrase grabber. To use it, set the * environment variable SSH_ASKPASS to point to the location of * gnome-ssh-askpass before calling "ssh-add < /dev/null". * * There is only two run-time options: if you set the environment variable * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the * pointer will be grabbed too. These may have some benefit to security if * you don't trust your X server. We grab the keyboard always. */ /* * Compile with: * * cc `gnome-config --cflags gnome gnomeui` \ * gnome-ssh-askpass1.c -o gnome-ssh-askpass \ * `gnome-config --libs gnome gnomeui` * */ #include #include #include #include #include #include void report_failed_grab (void) { GtkWidget *err; err = gnome_message_box_new("Could not grab keyboard or mouse.\n" "A malicious client may be eavesdropping on your session.", GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); gnome_dialog_run_and_close(GNOME_DIALOG(err)); } int passphrase_dialog(char *message) { char *passphrase; char **messages; int result, i, grab_server, grab_pointer; GtkWidget *dialog, *entry, *label; grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL); messages = g_strsplit(message, "\\n", 0); if (messages) for(i = 0; messages[i]; i++) { label = gtk_label_new(messages[i]); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), label, FALSE, FALSE, 0); } entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, FALSE, 0); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); /* Center window and prepare for grab */ gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), GNOME_PAD); gtk_widget_show_all(dialog); /* Grab focus */ if (grab_server) XGrabServer(GDK_DISPLAY()); if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0, NULL, NULL, GDK_CURRENT_TIME)) goto nograb; if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) goto nograbkb; /* Make close dialog */ gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); /* Run dialog */ result = gnome_dialog_run(GNOME_DIALOG(dialog)); /* Ungrab */ if (grab_server) XUngrabServer(GDK_DISPLAY()); if (grab_pointer) gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_keyboard_ungrab(GDK_CURRENT_TIME); gdk_flush(); /* Report passphrase if user selected OK */ passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); if (result == 0) puts(passphrase); /* Zero passphrase in memory */ memset(passphrase, '\0', strlen(passphrase)); gtk_entry_set_text(GTK_ENTRY(entry), passphrase); gnome_dialog_close(GNOME_DIALOG(dialog)); return (result == 0 ? 0 : -1); /* At least one grab failed - ungrab what we got, and report the failure to the user. Note that XGrabServer() cannot fail. */ nograbkb: gdk_pointer_ungrab(GDK_CURRENT_TIME); nograb: if (grab_server) XUngrabServer(GDK_DISPLAY()); gnome_dialog_close(GNOME_DIALOG(dialog)); report_failed_grab(); return (-1); } int main(int argc, char **argv) { char *message; int result; gnome_init("GNOME ssh-askpass", "0.1", argc, argv); if (argc == 2) message = argv[1]; else message = "Enter your OpenSSH passphrase:"; setvbuf(stdout, 0, _IONBF, 0); result = passphrase_dialog(message); return (result); } openssh-7.2p2/contrib/gnome-ssh-askpass2.c010064400017500001750000000143151267006270000167070ustar00djmdjm/* * Copyright (c) 2000-2002 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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. */ /* GTK2 support by Nalin Dahyabhai */ /* * This is a simple GNOME SSH passphrase grabber. To use it, set the * environment variable SSH_ASKPASS to point to the location of * gnome-ssh-askpass before calling "ssh-add < /dev/null". * * There is only two run-time options: if you set the environment variable * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the * pointer will be grabbed too. These may have some benefit to security if * you don't trust your X server. We grab the keyboard always. */ #define GRAB_TRIES 16 #define GRAB_WAIT 250 /* milliseconds */ /* * Compile with: * * cc -Wall `pkg-config --cflags gtk+-2.0` \ * gnome-ssh-askpass2.c -o gnome-ssh-askpass \ * `pkg-config --libs gtk+-2.0` * */ #include #include #include #include #include #include #include static void report_failed_grab (const char *what) { GtkWidget *err; err = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Could not grab %s. " "A malicious client may be eavesdropping " "on your session.", what); gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), TRUE); gtk_dialog_run(GTK_DIALOG(err)); gtk_widget_destroy(err); } static void ok_dialog(GtkWidget *entry, gpointer dialog) { g_return_if_fail(GTK_IS_DIALOG(dialog)); gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); } static int passphrase_dialog(char *message) { const char *failed; char *passphrase, *local; int result, grab_tries, grab_server, grab_pointer; GtkWidget *dialog, *entry; GdkGrabStatus status; grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); grab_tries = 0; dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "%s", message); entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, FALSE, 0); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); gtk_widget_show(entry); gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), TRUE); /* Make close dialog */ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(ok_dialog), dialog); gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); /* Grab focus */ gtk_widget_show_now(dialog); if (grab_pointer) { for(;;) { status = gdk_pointer_grab( (GTK_WIDGET(dialog))->window, TRUE, 0, NULL, NULL, GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) break; usleep(GRAB_WAIT * 1000); if (++grab_tries > GRAB_TRIES) { failed = "mouse"; goto nograb; } } } for(;;) { status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, FALSE, GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) break; usleep(GRAB_WAIT * 1000); if (++grab_tries > GRAB_TRIES) { failed = "keyboard"; goto nograbkb; } } if (grab_server) { gdk_x11_grab_server(); } result = gtk_dialog_run(GTK_DIALOG(dialog)); /* Ungrab */ if (grab_server) XUngrabServer(GDK_DISPLAY()); if (grab_pointer) gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_keyboard_ungrab(GDK_CURRENT_TIME); gdk_flush(); /* Report passphrase if user selected OK */ passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); if (result == GTK_RESPONSE_OK) { local = g_locale_from_utf8(passphrase, strlen(passphrase), NULL, NULL, NULL); if (local != NULL) { puts(local); memset(local, '\0', strlen(local)); g_free(local); } else { puts(passphrase); } } /* Zero passphrase in memory */ memset(passphrase, '\b', strlen(passphrase)); gtk_entry_set_text(GTK_ENTRY(entry), passphrase); memset(passphrase, '\0', strlen(passphrase)); g_free(passphrase); gtk_widget_destroy(dialog); return (result == GTK_RESPONSE_OK ? 0 : -1); /* At least one grab failed - ungrab what we got, and report the failure to the user. Note that XGrabServer() cannot fail. */ nograbkb: gdk_pointer_ungrab(GDK_CURRENT_TIME); nograb: if (grab_server) XUngrabServer(GDK_DISPLAY()); gtk_widget_destroy(dialog); report_failed_grab(failed); return (-1); } int main(int argc, char **argv) { char *message; int result; gtk_init(&argc, &argv); if (argc > 1) { message = g_strjoinv(" ", argv + 1); } else { message = g_strdup("Enter your OpenSSH passphrase:"); } setvbuf(stdout, 0, _IONBF, 0); result = passphrase_dialog(message); g_free(message); return (result); } openssh-7.2p2/contrib/hpux004075500017500001750000000000001267006270000140225ustar00djmdjmopenssh-7.2p2/contrib/hpux/README010064400017500001750000000021641267006270000147610ustar00djmdjmREADME for OpenSSH HP-UX contrib files Kevin Steves sshd: configuration file for sshd.rc sshd.rc: SSH startup script egd: configuration file for egd.rc egd.rc: EGD (entropy gathering daemon) startup script To install: sshd.rc: o Verify paths in sshd.rc match your local installation (WHAT_PATH and WHAT_PID) o Customize sshd if needed (SSHD_ARGS) o Install: # cp sshd /etc/rc.config.d # chmod 444 /etc/rc.config.d/sshd # cp sshd.rc /sbin/init.d # chmod 555 /sbin/init.d/sshd.rc # ln -s /sbin/init.d/sshd.rc /sbin/rc1.d/K100sshd # ln -s /sbin/init.d/sshd.rc /sbin/rc2.d/S900sshd egd.rc: o Verify egd.pl path in egd.rc matches your local installation (WHAT_PATH) o Customize egd if needed (EGD_ARGS and EGD_LOG) o Add pseudo account: # groupadd egd # useradd -g egd egd # mkdir -p /etc/opt/egd # chown egd:egd /etc/opt/egd # chmod 711 /etc/opt/egd o Install: # cp egd /etc/rc.config.d # chmod 444 /etc/rc.config.d/egd # cp egd.rc /sbin/init.d # chmod 555 /sbin/init.d/egd.rc # ln -s /sbin/init.d/egd.rc /sbin/rc1.d/K600egd # ln -s /sbin/init.d/egd.rc /sbin/rc2.d/S400egd openssh-7.2p2/contrib/hpux/egd010064400017500001750000000006051267006270000145610ustar00djmdjm# EGD_START: Set to 1 to start entropy gathering daemon # EGD_ARGS: Command line arguments to pass to egd # EGD_LOG: EGD stdout and stderr log file (default /etc/opt/egd/egd.log) # # To configure the egd environment: # groupadd egd # useradd -g egd egd # mkdir -p /etc/opt/egd # chown egd:egd /etc/opt/egd # chmod 711 /etc/opt/egd EGD_START=1 EGD_ARGS='/etc/opt/egd/entropy' EGD_LOG= openssh-7.2p2/contrib/hpux/egd.rc010075500017500001750000000042471267006270000151750ustar00djmdjm#!/sbin/sh # # egd.rc: EGD start-up and shutdown script # # Allowed exit values: # 0 = success; causes "OK" to show up in checklist. # 1 = failure; causes "FAIL" to show up in checklist. # 2 = skip; causes "N/A" to show up in the checklist. # Use this value if execution of this script is overridden # by the use of a control variable, or if this script is not # appropriate to execute for some other reason. # 3 = reboot; causes the system to be rebooted after execution. # Input and output: # stdin is redirected from /dev/null # # stdout and stderr are redirected to the /etc/rc.log file # during checklist mode, or to the console in raw mode. umask 022 PATH=/usr/sbin:/usr/bin:/sbin export PATH WHAT='EGD (entropy gathering daemon)' WHAT_PATH=/opt/perl/bin/egd.pl WHAT_CONFIG=/etc/rc.config.d/egd WHAT_LOG=/etc/opt/egd/egd.log # NOTE: If your script executes in run state 0 or state 1, then /usr might # not be available. Do not attempt to access commands or files in # /usr unless your script executes in run state 2 or greater. Other # file systems typically not mounted until run state 2 include /var # and /opt. rval=0 # Check the exit value of a command run by this script. If non-zero, the # exit code is echoed to the log file and the return value of this script # is set to indicate failure. set_return() { x=$? if [ $x -ne 0 ]; then echo "EXIT CODE: $x" rval=1 # script FAILed fi } case $1 in 'start_msg') echo "Starting $WHAT" ;; 'stop_msg') echo "Stopping $WHAT" ;; 'start') if [ -f $WHAT_CONFIG ] ; then . $WHAT_CONFIG else echo "ERROR: $WHAT_CONFIG defaults file MISSING" fi if [ "$EGD_START" -eq 1 -a -x $WHAT_PATH ]; then EGD_LOG=${EGD_LOG:-$WHAT_LOG} su egd -c "nohup $WHAT_PATH $EGD_ARGS >$EGD_LOG 2>&1" && echo $WHAT started set_return else rval=2 fi ;; 'stop') pid=`ps -fuegd | awk '$1 == "egd" { print $2 }'` if [ "X$pid" != "X" ]; then if kill "$pid"; then echo "$WHAT stopped" else rval=1 echo "Unable to stop $WHAT" fi fi set_return ;; *) echo "usage: $0 {start|stop|start_msg|stop_msg}" rval=1 ;; esac exit $rval openssh-7.2p2/contrib/hpux/sshd010064400017500001750000000001731267006270000147630ustar00djmdjm# SSHD_START: Set to 1 to start SSH daemon # SSHD_ARGS: Command line arguments to pass to sshd # SSHD_START=1 SSHD_ARGS= openssh-7.2p2/contrib/hpux/sshd.rc010075500017500001750000000036661267006270000154030ustar00djmdjm#!/sbin/sh # # sshd.rc: SSH daemon start-up and shutdown script # # Allowed exit values: # 0 = success; causes "OK" to show up in checklist. # 1 = failure; causes "FAIL" to show up in checklist. # 2 = skip; causes "N/A" to show up in the checklist. # Use this value if execution of this script is overridden # by the use of a control variable, or if this script is not # appropriate to execute for some other reason. # 3 = reboot; causes the system to be rebooted after execution. # Input and output: # stdin is redirected from /dev/null # # stdout and stderr are redirected to the /etc/rc.log file # during checklist mode, or to the console in raw mode. PATH=/usr/sbin:/usr/bin:/sbin export PATH WHAT='OpenSSH' WHAT_PATH=/opt/openssh/sbin/sshd WHAT_PID=/var/run/sshd.pid WHAT_CONFIG=/etc/rc.config.d/sshd # NOTE: If your script executes in run state 0 or state 1, then /usr might # not be available. Do not attempt to access commands or files in # /usr unless your script executes in run state 2 or greater. Other # file systems typically not mounted until run state 2 include /var # and /opt. rval=0 # Check the exit value of a command run by this script. If non-zero, the # exit code is echoed to the log file and the return value of this script # is set to indicate failure. set_return() { x=$? if [ $x -ne 0 ]; then echo "EXIT CODE: $x" rval=1 # script FAILed fi } case $1 in 'start_msg') echo "Starting $WHAT" ;; 'stop_msg') echo "Stopping $WHAT" ;; 'start') if [ -f $WHAT_CONFIG ] ; then . $WHAT_CONFIG else echo "ERROR: $WHAT_CONFIG defaults file MISSING" fi if [ "$SSHD_START" -eq 1 -a -x "$WHAT_PATH" ]; then $WHAT_PATH $SSHD_ARGS && echo "$WHAT started" set_return else rval=2 fi ;; 'stop') if kill `cat $WHAT_PID`; then echo "$WHAT stopped" else rval=1 echo "Unable to stop $WHAT" fi set_return ;; *) echo "usage: $0 {start|stop|start_msg|stop_msg}" rval=1 ;; esac exit $rval openssh-7.2p2/contrib/redhat004075500017500001750000000000001267006270000143055ustar00djmdjmopenssh-7.2p2/contrib/redhat/gnome-ssh-askpass.csh010064400017500001750000000000721267006270000204220ustar00djmdjmsetenv SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass openssh-7.2p2/contrib/redhat/gnome-ssh-askpass.sh010064400017500001750000000001061267006270000202550ustar00djmdjmSSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass export SSH_ASKPASS openssh-7.2p2/contrib/redhat/openssh.spec010064400017500001750000000701261267006270000167220ustar00djmdjm%define ver 7.2p2 %define rel 1 # OpenSSH privilege separation requires a user & group ID %define sshd_uid 74 %define sshd_gid 74 # Version of ssh-askpass %define aversion 1.2.4.1 # Do we want to disable building of x11-askpass? (1=yes 0=no) %define no_x11_askpass 0 # Do we want to disable building of gnome-askpass? (1=yes 0=no) %define no_gnome_askpass 0 # Do we want to link against a static libcrypto? (1=yes 0=no) %define static_libcrypto 0 # Do we want smartcard support (1=yes 0=no) %define scard 0 # Use GTK2 instead of GNOME in gnome-ssh-askpass %define gtk2 1 # Is this build for RHL 6.x? %define build6x 0 # Do we want kerberos5 support (1=yes 0=no) %define kerberos5 1 # Reserve options to override askpass settings with: # rpm -ba|--rebuild --define 'skip_xxx 1' %{?skip_x11_askpass:%define no_x11_askpass 1} %{?skip_gnome_askpass:%define no_gnome_askpass 1} # Add option to build without GTK2 for older platforms with only GTK+. # RedHat <= 7.2 and Red Hat Advanced Server 2.1 are examples. # rpm -ba|--rebuild --define 'no_gtk2 1' %{?no_gtk2:%define gtk2 0} # Is this a build for RHL 6.x or earlier? %{?build_6x:%define build6x 1} # If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc. %if %{build6x} %define _sysconfdir /etc %endif # Options for static OpenSSL link: # rpm -ba|--rebuild --define "static_openssl 1" %{?static_openssl:%define static_libcrypto 1} # Options for Smartcard support: (needs libsectok and openssl-engine) # rpm -ba|--rebuild --define "smartcard 1" %{?smartcard:%define scard 1} # Is this a build for the rescue CD (without PAM, with MD5)? (1=yes 0=no) %define rescue 0 %{?build_rescue:%define rescue 1} # Turn off some stuff for resuce builds %if %{rescue} %define kerberos5 0 %endif Summary: The OpenSSH implementation of SSH protocol versions 1 and 2. Name: openssh Version: %{ver} %if %{rescue} Release: %{rel}rescue %else Release: %{rel} %endif URL: http://www.openssh.com/portable.html Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz %if ! %{no_x11_askpass} Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz %endif License: BSD Group: Applications/Internet BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot Obsoletes: ssh %if %{build6x} PreReq: initscripts >= 5.00 %else Requires: initscripts >= 5.20 %endif BuildRequires: perl, openssl-devel BuildRequires: /bin/login %if ! %{build6x} BuildRequires: glibc-devel, pam %else BuildRequires: /usr/include/security/pam_appl.h %endif %if ! %{no_x11_askpass} BuildRequires: /usr/include/X11/Xlib.h %endif %if ! %{no_gnome_askpass} BuildRequires: pkgconfig %endif %if %{kerberos5} BuildRequires: krb5-devel BuildRequires: krb5-libs %endif %package clients Summary: OpenSSH clients. Requires: openssh = %{version}-%{release} Group: Applications/Internet Obsoletes: ssh-clients %package server Summary: The OpenSSH server daemon. Group: System Environment/Daemons Obsoletes: ssh-server Requires: openssh = %{version}-%{release}, chkconfig >= 0.9 %if ! %{build6x} Requires: /etc/pam.d/system-auth %endif %package askpass Summary: A passphrase dialog for OpenSSH and X. Group: Applications/Internet Requires: openssh = %{version}-%{release} Obsoletes: ssh-extras %package askpass-gnome Summary: A passphrase dialog for OpenSSH, X, and GNOME. Group: Applications/Internet Requires: openssh = %{version}-%{release} Obsoletes: ssh-extras %description SSH (Secure SHell) is a program for logging into and executing commands on a remote machine. SSH is intended to replace rlogin and rsh, and to provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections and arbitrary TCP/IP ports can also be forwarded over the secure channel. OpenSSH is OpenBSD's version of the last free version of SSH, bringing it up to date in terms of security and features, as well as removing all patented algorithms to separate libraries. This package includes the core files necessary for both the OpenSSH client and server. To make this package useful, you should also install openssh-clients, openssh-server, or both. %description clients OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package includes the clients necessary to make encrypted connections to SSH servers. You'll also need to install the openssh package on OpenSSH clients. %description server OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains the secure shell daemon (sshd). The sshd daemon allows SSH clients to securely connect to your SSH server. You also need to have the openssh package installed. %description askpass OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains an X11 passphrase dialog for OpenSSH. %description askpass-gnome OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains an X11 passphrase dialog for OpenSSH and the GNOME GUI desktop environment. %prep %if ! %{no_x11_askpass} %setup -q -a 1 %else %setup -q %endif %build %if %{rescue} CFLAGS="$RPM_OPT_FLAGS -Os"; export CFLAGS %endif %if %{kerberos5} K5DIR=`rpm -ql krb5-devel | grep 'include/krb5\.h' | sed 's,\/include\/krb5.h,,'` echo K5DIR=$K5DIR %endif %configure \ --sysconfdir=%{_sysconfdir}/ssh \ --libexecdir=%{_libexecdir}/openssh \ --datadir=%{_datadir}/openssh \ --with-default-path=/usr/local/bin:/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/sshd \ --with-md5-passwords \ %if %{scard} --with-smartcard \ %endif %if %{rescue} --without-pam \ %else --with-pam \ %endif %if %{kerberos5} --with-kerberos5=$K5DIR \ %endif %if %{static_libcrypto} perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile %endif make %if ! %{no_x11_askpass} pushd x11-ssh-askpass-%{aversion} %configure --libexecdir=%{_libexecdir}/openssh xmkmf -a make popd %endif # Define a variable to toggle gnome1/gtk2 building. This is necessary # because RPM doesn't handle nested %if statements. %if %{gtk2} gtk2=yes %else gtk2=no %endif %if ! %{no_gnome_askpass} pushd contrib if [ $gtk2 = yes ] ; then make gnome-ssh-askpass2 mv gnome-ssh-askpass2 gnome-ssh-askpass else make gnome-ssh-askpass1 mv gnome-ssh-askpass1 gnome-ssh-askpass fi popd %endif %install rm -rf $RPM_BUILD_ROOT mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd make install DESTDIR=$RPM_BUILD_ROOT install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/rc.d/init.d install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh %if %{build6x} install -m644 contrib/redhat/sshd.pam.old $RPM_BUILD_ROOT/etc/pam.d/sshd %else install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd %endif install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd %if ! %{no_x11_askpass} install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/x11-ssh-askpass ln -s x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass %endif %if ! %{no_gnome_askpass} install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass %endif %if ! %{scard} rm -f $RPM_BUILD_ROOT/usr/share/openssh/Ssh.bin %endif %if ! %{no_gnome_askpass} install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ install -m 755 contrib/redhat/gnome-ssh-askpass.csh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ %endif perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* %clean rm -rf $RPM_BUILD_ROOT %triggerun server -- ssh-server if [ "$1" != 0 -a -r /var/run/sshd.pid ] ; then touch /var/run/sshd.restart fi %triggerun server -- openssh-server < 2.5.0p1 # Count the number of HostKey and HostDsaKey statements we have. gawk 'BEGIN {IGNORECASE=1} /^hostkey/ || /^hostdsakey/ {sawhostkey = sawhostkey + 1} END {exit sawhostkey}' /etc/ssh/sshd_config # And if we only found one, we know the client was relying on the old default # behavior, which loaded the the SSH2 DSA host key when HostDsaKey wasn't # specified. Now that HostKey is used for both SSH1 and SSH2 keys, specifying # one nullifies the default, which would have loaded both. if [ $? -eq 1 ] ; then echo HostKey /etc/ssh/ssh_host_rsa_key >> /etc/ssh/sshd_config echo HostKey /etc/ssh/ssh_host_dsa_key >> /etc/ssh/sshd_config fi %triggerpostun server -- ssh-server if [ "$1" != 0 ] ; then /sbin/chkconfig --add sshd if test -f /var/run/sshd.restart ; then rm -f /var/run/sshd.restart /sbin/service sshd start > /dev/null 2>&1 || : fi fi %pre server %{_sbindir}/groupadd -r -g %{sshd_gid} sshd 2>/dev/null || : %{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \ -g sshd -M -r sshd 2>/dev/null || : %post server /sbin/chkconfig --add sshd %postun server /sbin/service sshd condrestart > /dev/null 2>&1 || : %preun server if [ "$1" = 0 ] then /sbin/service sshd stop > /dev/null 2>&1 || : /sbin/chkconfig --del sshd fi %files %defattr(-,root,root) %doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO %attr(0755,root,root) %{_bindir}/scp %attr(0644,root,root) %{_mandir}/man1/scp.1* %attr(0755,root,root) %dir %{_sysconfdir}/ssh %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli %if ! %{rescue} %attr(0755,root,root) %{_bindir}/ssh-keygen %attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* %attr(0755,root,root) %dir %{_libexecdir}/openssh %attr(4711,root,root) %{_libexecdir}/openssh/ssh-keysign %attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper %attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8* %attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* %endif %if %{scard} %attr(0755,root,root) %dir %{_datadir}/openssh %attr(0644,root,root) %{_datadir}/openssh/Ssh.bin %endif %files clients %defattr(-,root,root) %attr(0755,root,root) %{_bindir}/ssh %attr(0644,root,root) %{_mandir}/man1/ssh.1* %attr(0644,root,root) %{_mandir}/man5/ssh_config.5* %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config %attr(-,root,root) %{_bindir}/slogin %attr(-,root,root) %{_mandir}/man1/slogin.1* %if ! %{rescue} %attr(2755,root,nobody) %{_bindir}/ssh-agent %attr(0755,root,root) %{_bindir}/ssh-add %attr(0755,root,root) %{_bindir}/ssh-keyscan %attr(0755,root,root) %{_bindir}/sftp %attr(0644,root,root) %{_mandir}/man1/ssh-agent.1* %attr(0644,root,root) %{_mandir}/man1/ssh-add.1* %attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* %attr(0644,root,root) %{_mandir}/man1/sftp.1* %endif %if ! %{rescue} %files server %defattr(-,root,root) %dir %attr(0111,root,root) %{_var}/empty/sshd %attr(0755,root,root) %{_sbindir}/sshd %attr(0755,root,root) %{_libexecdir}/openssh/sftp-server %attr(0644,root,root) %{_mandir}/man8/sshd.8* %attr(0644,root,root) %{_mandir}/man5/moduli.5* %attr(0644,root,root) %{_mandir}/man5/sshd_config.5* %attr(0644,root,root) %{_mandir}/man8/sftp-server.8* %attr(0755,root,root) %dir %{_sysconfdir}/ssh %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config %attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd %attr(0755,root,root) %config /etc/rc.d/init.d/sshd %endif %if ! %{no_x11_askpass} %files askpass %defattr(-,root,root) %doc x11-ssh-askpass-%{aversion}/README %doc x11-ssh-askpass-%{aversion}/ChangeLog %doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad %attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass %attr(0755,root,root) %{_libexecdir}/openssh/x11-ssh-askpass %endif %if ! %{no_gnome_askpass} %files askpass-gnome %defattr(-,root,root) %attr(0755,root,root) %config %{_sysconfdir}/profile.d/gnome-ssh-askpass.* %attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass %endif %changelog * Wed Jul 14 2010 Tim Rice - test for skip_x11_askpass (line 77) should have been for no_x11_askpass * Mon Jun 2 2003 Damien Miller - Remove noip6 option. This may be controlled at run-time in client config file using new AddressFamily directive * Mon May 12 2003 Damien Miller - Don't install profile.d scripts when not building with GNOME/GTK askpass (patch from bet@rahul.net) * Wed Oct 01 2002 Damien Miller - Install ssh-agent setgid nobody to prevent ptrace() key theft attacks * Mon Sep 30 2002 Damien Miller - Use contrib/ Makefile for building askpass programs * Fri Jun 21 2002 Damien Miller - Merge in spec changes from seba@iq.pl (Sebastian Pachuta) - Add new {ssh,sshd}_config.5 manpages - Add new ssh-keysign program and remove setuid from ssh client * Fri May 10 2002 Damien Miller - Merge in spec changes from RedHat, reorgansie a little - Add Privsep user, group and directory * Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-2 - bump and grind (through the build system) * Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-1 - require sharutils for building (mindrot #137) - require db1-devel only when building for 6.x (#55105), which probably won't work anyway (3.1 requires OpenSSL 0.9.6 to build), but what the heck - require pam-devel by file (not by package name) again - add Markus's patch to compile with OpenSSL 0.9.5a (from http://bugzilla.mindrot.org/show_bug.cgi?id=141) and apply it if we're building for 6.x * Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-0 - update to 3.1p1 * Tue Mar 5 2002 Nalin Dahyabhai SNAP-20020305 - update to SNAP-20020305 - drop debug patch, fixed upstream * Wed Feb 20 2002 Nalin Dahyabhai SNAP-20020220 - update to SNAP-20020220 for testing purposes (you've been warned, if there's anything to be warned about, gss patches won't apply, I don't mind) * Wed Feb 13 2002 Nalin Dahyabhai 3.0.2p1-3 - add patches from Simon Wilkinson and Nicolas Williams for GSSAPI key exchange, authentication, and named key support * Wed Jan 23 2002 Nalin Dahyabhai 3.0.2p1-2 - remove dependency on db1-devel, which has just been swallowed up whole by gnome-libs-devel * Sun Dec 29 2001 Nalin Dahyabhai - adjust build dependencies so that build6x actually works right (fix from Hugo van der Kooij) * Tue Dec 4 2001 Nalin Dahyabhai 3.0.2p1-1 - update to 3.0.2p1 * Fri Nov 16 2001 Nalin Dahyabhai 3.0.1p1-1 - update to 3.0.1p1 * Tue Nov 13 2001 Nalin Dahyabhai - update to current CVS (not for use in distribution) * Thu Nov 8 2001 Nalin Dahyabhai 3.0p1-1 - merge some of Damien Miller changes from the upstream 3.0p1 spec file and init script * Wed Nov 7 2001 Nalin Dahyabhai - update to 3.0p1 - update to x11-ssh-askpass 1.2.4.1 - change build dependency on a file from pam-devel to the pam-devel package - replace primes with moduli * Thu Sep 27 2001 Nalin Dahyabhai 2.9p2-9 - incorporate fix from Markus Friedl's advisory for IP-based authorization bugs * Thu Sep 13 2001 Bernhard Rosenkraenzer 2.9p2-8 - Merge changes to rescue build from current sysadmin survival cd * Thu Sep 6 2001 Nalin Dahyabhai 2.9p2-7 - fix scp's server's reporting of file sizes, and build with the proper preprocessor define to get large-file capable open(), stat(), etc. (sftp has been doing this correctly all along) (#51827) - configure without --with-ipv4-default on RHL 7.x and newer (#45987,#52247) - pull cvs patch to fix support for /etc/nologin for non-PAM logins (#47298) - mark profile.d scriptlets as config files (#42337) - refer to Jason Stone's mail for zsh workaround for exit-hanging quasi-bug - change a couple of log() statements to debug() statements (#50751) - pull cvs patch to add -t flag to sshd (#28611) - clear fd_sets correctly (one bit per FD, not one byte per FD) (#43221) * Mon Aug 20 2001 Nalin Dahyabhai 2.9p2-6 - add db1-devel as a BuildPrerequisite (noted by Hans Ecke) * Thu Aug 16 2001 Nalin Dahyabhai - pull cvs patch to fix remote port forwarding with protocol 2 * Thu Aug 9 2001 Nalin Dahyabhai - pull cvs patch to add session initialization to no-pty sessions - pull cvs patch to not cut off challengeresponse auth needlessly - refuse to do X11 forwarding if xauth isn't there, handy if you enable it by default on a system that doesn't have X installed (#49263) * Wed Aug 8 2001 Nalin Dahyabhai - don't apply patches to code we don't intend to build (spotted by Matt Galgoci) * Mon Aug 6 2001 Nalin Dahyabhai - pass OPTIONS correctly to initlog (#50151) * Wed Jul 25 2001 Nalin Dahyabhai - switch to x11-ssh-askpass 1.2.2 * Wed Jul 11 2001 Nalin Dahyabhai - rebuild in new environment * Mon Jun 25 2001 Nalin Dahyabhai - disable the gssapi patch * Mon Jun 18 2001 Nalin Dahyabhai - update to 2.9p2 - refresh to a new version of the gssapi patch * Thu Jun 7 2001 Nalin Dahyabhai - change Copyright: BSD to License: BSD - add Markus Friedl's unverified patch for the cookie file deletion problem so that we can verify it - drop patch to check if xauth is present (was folded into cookie patch) - don't apply gssapi patches for the errata candidate - clear supplemental groups list at startup * Fri May 25 2001 Nalin Dahyabhai - fix an error parsing the new default sshd_config - add a fix from Markus Friedl (via openssh-unix-dev) for ssh-keygen not dealing with comments right * Thu May 24 2001 Nalin Dahyabhai - add in Simon Wilkinson's GSSAPI patch to give it some testing in-house, to be removed before the next beta cycle because it's a big departure from the upstream version * Thu May 3 2001 Nalin Dahyabhai - finish marking strings in the init script for translation - modify init script to source /etc/sysconfig/sshd and pass $OPTIONS to sshd at startup (change merged from openssh.com init script, originally by Pekka Savola) - refuse to do X11 forwarding if xauth isn't there, handy if you enable it by default on a system that doesn't have X installed * Wed May 2 2001 Nalin Dahyabhai - update to 2.9 - drop various patches that came from or went upstream or to or from CVS * Wed Apr 18 2001 Nalin Dahyabhai - only require initscripts 5.00 on 6.2 (reported by Peter Bieringer) * Sun Apr 8 2001 Preston Brown - remove explicit openssl requirement, fixes builddistro issue - make initscript stop() function wait until sshd really dead to avoid races in condrestart * Mon Apr 2 2001 Nalin Dahyabhai - mention that challengereponse supports PAM, so disabling password doesn't limit users to pubkey and rsa auth (#34378) - bypass the daemon() function in the init script and call initlog directly, because daemon() won't start a daemon it detects is already running (like open connections) - require the version of openssl we had when we were built * Fri Mar 23 2001 Nalin Dahyabhai - make do_pam_setcred() smart enough to know when to establish creds and when to reinitialize them - add in a couple of other fixes from Damien for inclusion in the errata * Thu Mar 22 2001 Nalin Dahyabhai - update to 2.5.2p2 - call setcred() again after initgroups, because the "creds" could actually be group memberships * Tue Mar 20 2001 Nalin Dahyabhai - update to 2.5.2p1 (includes endianness fixes in the rijndael implementation) - don't enable challenge-response by default until we find a way to not have too many userauth requests (we may make up to six pubkey and up to three password attempts as it is) - remove build dependency on rsh to match openssh.com's packages more closely * Sat Mar 3 2001 Nalin Dahyabhai - remove dependency on openssl -- would need to be too precise * Fri Mar 2 2001 Nalin Dahyabhai - rebuild in new environment * Mon Feb 26 2001 Nalin Dahyabhai - Revert the patch to move pam_open_session. - Init script and spec file changes from Pekka Savola. (#28750) - Patch sftp to recognize '-o protocol' arguments. (#29540) * Thu Feb 22 2001 Nalin Dahyabhai - Chuck the closing patch. - Add a trigger to add host keys for protocol 2 to the config file, now that configuration file syntax requires us to specify it with HostKey if we specify any other HostKey values, which we do. * Tue Feb 20 2001 Nalin Dahyabhai - Redo patch to move pam_open_session after the server setuid()s to the user. - Rework the nopam patch to use be picked up by autoconf. * Mon Feb 19 2001 Nalin Dahyabhai - Update for 2.5.1p1. - Add init script mods from Pekka Savola. - Tweak the init script to match the CVS contrib script more closely. - Redo patch to ssh-add to try to adding both identity and id_dsa to also try adding id_rsa. * Fri Feb 16 2001 Nalin Dahyabhai - Update for 2.5.0p1. - Use $RPM_OPT_FLAGS instead of -O when building gnome-ssh-askpass - Resync with parts of Damien Miller's openssh.spec from CVS, including update of x11 askpass to 1.2.0. - Only require openssl (don't prereq) because we generate keys in the init script now. * Tue Feb 13 2001 Nalin Dahyabhai - Don't open a PAM session until we've forked and become the user (#25690). - Apply Andrew Bartlett's patch for letting pam_authenticate() know which host the user is attempting a login from. - Resync with parts of Damien Miller's openssh.spec from CVS. - Don't expose KbdInt responses in debug messages (from CVS). - Detect and handle errors in rsa_{public,private}_decrypt (from CVS). * Wed Feb 7 2001 Trond Eivind Glomsrxd - i18n-tweak to initscript. * Tue Jan 23 2001 Nalin Dahyabhai - More gettextizing. - Close all files after going into daemon mode (needs more testing). - Extract patch from CVS to handle auth banners (in the client). - Extract patch from CVS to handle compat weirdness. * Fri Jan 19 2001 Nalin Dahyabhai - Finish with the gettextizing. * Thu Jan 18 2001 Nalin Dahyabhai - Fix a bug in auth2-pam.c (#23877) - Gettextize the init script. * Wed Dec 20 2000 Nalin Dahyabhai - Incorporate a switch for using PAM configs for 6.x, just in case. * Tue Dec 5 2000 Nalin Dahyabhai - Incorporate Bero's changes for a build specifically for rescue CDs. * Wed Nov 29 2000 Nalin Dahyabhai - Don't treat pam_setcred() failure as fatal unless pam_authenticate() has succeeded, to allow public-key authentication after a failure with "none" authentication. (#21268) * Tue Nov 28 2000 Nalin Dahyabhai - Update to x11-askpass 1.1.1. (#21301) - Don't second-guess fixpaths, which causes paths to get fixed twice. (#21290) * Mon Nov 27 2000 Nalin Dahyabhai - Merge multiple PAM text messages into subsequent prompts when possible when doing keyboard-interactive authentication. * Sun Nov 26 2000 Nalin Dahyabhai - Disable the built-in MD5 password support. We're using PAM. - Take a crack at doing keyboard-interactive authentication with PAM, and enable use of it in the default client configuration so that the client will try it when the server disallows password authentication. - Build with debugging flags. Build root policies strip all binaries anyway. * Tue Nov 21 2000 Nalin Dahyabhai - Use DESTDIR instead of %%makeinstall. - Remove /usr/X11R6/bin from the path-fixing patch. * Mon Nov 20 2000 Nalin Dahyabhai - Add the primes file from the latest snapshot to the main package (#20884). - Add the dev package to the prereq list (#19984). - Remove the default path and mimic login's behavior in the server itself. * Fri Nov 17 2000 Nalin Dahyabhai - Resync with conditional options in Damien Miller's .spec file for an errata. - Change libexecdir from %%{_libexecdir}/ssh to %%{_libexecdir}/openssh. * Tue Nov 7 2000 Nalin Dahyabhai - Update to OpenSSH 2.3.0p1. - Update to x11-askpass 1.1.0. - Enable keyboard-interactive authentication. * Mon Oct 30 2000 Nalin Dahyabhai - Update to ssh-askpass-x11 1.0.3. - Change authentication related messages to be private (#19966). * Tue Oct 10 2000 Nalin Dahyabhai - Patch ssh-keygen to be able to list signatures for DSA public key files it generates. * Thu Oct 5 2000 Nalin Dahyabhai - Add BuildRequires on /usr/include/security/pam_appl.h to be sure we always build PAM authentication in. - Try setting SSH_ASKPASS if gnome-ssh-askpass is installed. - Clean out no-longer-used patches. - Patch ssh-add to try to add both identity and id_dsa, and to error only when neither exists. * Mon Oct 2 2000 Nalin Dahyabhai - Update x11-askpass to 1.0.2. (#17835) - Add BuildRequiress for /bin/login and /usr/bin/rsh so that configure will always find them in the right place. (#17909) - Set the default path to be the same as the one supplied by /bin/login, but add /usr/X11R6/bin. (#17909) - Try to handle obsoletion of ssh-server more cleanly. Package names are different, but init script name isn't. (#17865) * Wed Sep 6 2000 Nalin Dahyabhai - Update to 2.2.0p1. (#17835) - Tweak the init script to allow proper restarting. (#18023) * Wed Aug 23 2000 Nalin Dahyabhai - Update to 20000823 snapshot. - Change subpackage requirements from %%{version} to %%{version}-%%{release} - Back out the pipe patch. * Mon Jul 17 2000 Nalin Dahyabhai - Update to 2.1.1p4, which includes fixes for config file parsing problems. - Move the init script back. - Add Damien's quick fix for wackiness. * Wed Jul 12 2000 Nalin Dahyabhai - Update to 2.1.1p3, which includes fixes for X11 forwarding and strtok(). * Thu Jul 6 2000 Nalin Dahyabhai - Move condrestart to server postun. - Move key generation to init script. - Actually use the right patch for moving the key generation to the init script. - Clean up the init script a bit. * Wed Jul 5 2000 Nalin Dahyabhai - Fix X11 forwarding, from mail post by Chan Shih-Ping Richard. * Sun Jul 2 2000 Nalin Dahyabhai - Update to 2.1.1p2. - Use of strtok() considered harmful. * Sat Jul 1 2000 Nalin Dahyabhai - Get the build root out of the man pages. * Thu Jun 29 2000 Nalin Dahyabhai - Add and use condrestart support in the init script. - Add newer initscripts as a prereq. * Tue Jun 27 2000 Nalin Dahyabhai - Build in new environment (release 2) - Move -clients subpackage to Applications/Internet group * Fri Jun 9 2000 Nalin Dahyabhai - Update to 2.2.1p1 * Sat Jun 3 2000 Nalin Dahyabhai - Patch to build with neither RSA nor RSAref. - Miscellaneous FHS-compliance tweaks. - Fix for possibly-compressed man pages. * Wed Mar 15 2000 Damien Miller - Updated for new location - Updated for new gnome-ssh-askpass build * Sun Dec 26 1999 Damien Miller - Added Jim Knoble's askpass * Mon Nov 15 1999 Damien Miller - Split subpackages further based on patch from jim knoble * Sat Nov 13 1999 Damien Miller - Added 'Obsoletes' directives * Tue Nov 09 1999 Damien Miller - Use make install - Subpackages * Mon Nov 08 1999 Damien Miller - Added links for slogin - Fixed perms on manpages * Sat Oct 30 1999 Damien Miller - Renamed init script * Fri Oct 29 1999 Damien Miller - Back to old binary names * Thu Oct 28 1999 Damien Miller - Use autoconf - New binary names * Wed Oct 27 1999 Damien Miller - Initial RPMification, based on Jan "Yenya" Kasprzak's spec. openssh-7.2p2/contrib/redhat/sshd.init010075500017500001750000000033461267006270000162200ustar00djmdjm#!/bin/bash # # Init file for OpenSSH server daemon # # chkconfig: 2345 55 25 # description: OpenSSH server daemon # # processname: sshd # config: /etc/ssh/ssh_host_key # config: /etc/ssh/ssh_host_key.pub # config: /etc/ssh/ssh_random_seed # config: /etc/ssh/sshd_config # pidfile: /var/run/sshd.pid # source function library . /etc/rc.d/init.d/functions # pull in sysconfig settings [ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd RETVAL=0 prog="sshd" # Some functions to make the below more readable SSHD=/usr/sbin/sshd PID_FILE=/var/run/sshd.pid do_restart_sanity_check() { $SSHD -t RETVAL=$? if [ $RETVAL -ne 0 ]; then failure $"Configuration file or keys are invalid" echo fi } start() { # Create keys if necessary /usr/bin/ssh-keygen -A if [ -x /sbin/restorecon ]; then /sbin/restorecon /etc/ssh/ssh_host_key.pub /sbin/restorecon /etc/ssh/ssh_host_rsa_key.pub /sbin/restorecon /etc/ssh/ssh_host_dsa_key.pub /sbin/restorecon /etc/ssh/ssh_host_ecdsa_key.pub fi echo -n $"Starting $prog:" $SSHD $OPTIONS && success || failure RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/sshd echo } stop() { echo -n $"Stopping $prog:" killproc $SSHD -TERM RETVAL=$? [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd echo } reload() { echo -n $"Reloading $prog:" killproc $SSHD -HUP RETVAL=$? echo } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; reload) reload ;; condrestart) if [ -f /var/lock/subsys/sshd ] ; then do_restart_sanity_check if [ $RETVAL -eq 0 ] ; then stop # avoid race sleep 3 start fi fi ;; status) status $SSHD RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}" RETVAL=1 esac exit $RETVAL openssh-7.2p2/contrib/redhat/sshd.init.old010075500017500001750000000057721267006270000170020ustar00djmdjm#!/bin/bash # # Init file for OpenSSH server daemon # # chkconfig: 2345 55 25 # description: OpenSSH server daemon # # processname: sshd # config: /etc/ssh/ssh_host_key # config: /etc/ssh/ssh_host_key.pub # config: /etc/ssh/ssh_random_seed # config: /etc/ssh/sshd_config # pidfile: /var/run/sshd.pid # source function library . /etc/rc.d/init.d/functions # pull in sysconfig settings [ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd RETVAL=0 prog="sshd" # Some functions to make the below more readable KEYGEN=/usr/bin/ssh-keygen SSHD=/usr/sbin/sshd RSA1_KEY=/etc/ssh/ssh_host_key RSA_KEY=/etc/ssh/ssh_host_rsa_key DSA_KEY=/etc/ssh/ssh_host_dsa_key PID_FILE=/var/run/sshd.pid my_success() { local msg if [ $# -gt 1 ]; then msg="$2" else msg="done" fi case "`type -type success`" in function) success "$1" ;; *) echo -n "${msg}" ;; esac } my_failure() { local msg if [ $# -gt 1 ]; then msg="$2" else msg="FAILED" fi case "`type -type failure`" in function) failure "$1" ;; *) echo -n "${msg}" ;; esac } do_rsa1_keygen() { if [ ! -s $RSA1_KEY ]; then echo -n "Generating SSH1 RSA host key: " if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then chmod 600 $RSA1_KEY chmod 644 $RSA1_KEY.pub my_success "RSA1 key generation" echo else my_failure "RSA1 key generation" echo exit 1 fi fi } do_rsa_keygen() { if [ ! -s $RSA_KEY ]; then echo -n "Generating SSH2 RSA host key: " if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then chmod 600 $RSA_KEY chmod 644 $RSA_KEY.pub my_success "RSA key generation" echo else my_failure "RSA key generation" echo exit 1 fi fi } do_dsa_keygen() { if [ ! -s $DSA_KEY ]; then echo -n "Generating SSH2 DSA host key: " if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then chmod 600 $DSA_KEY chmod 644 $DSA_KEY.pub my_success "DSA key generation" echo else my_failure "DSA key generation" echo exit 1 fi fi } do_restart_sanity_check() { $SSHD -t RETVAL=$? if [ ! "$RETVAL" = 0 ]; then my_failure "Configuration file or keys" echo fi } case "$1" in start) # Create keys if necessary do_rsa1_keygen; do_rsa_keygen; do_dsa_keygen; echo -n "Starting sshd: " if [ ! -f $PID_FILE ] ; then sshd $OPTIONS RETVAL=$? if [ "$RETVAL" = "0" ] ; then my_success "sshd startup" "sshd" touch /var/lock/subsys/sshd else my_failure "sshd startup" "" fi fi echo ;; stop) echo -n "Shutting down sshd: " if [ -f $PID_FILE ] ; then killproc sshd RETVAL=$? [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd fi echo ;; restart) do_restart_sanity_check $0 stop $0 start RETVAL=$? ;; condrestart) if [ -f /var/lock/subsys/sshd ] ; then do_restart_sanity_check $0 stop $0 start RETVAL=$? fi ;; status) status sshd RETVAL=$? ;; *) echo "Usage: sshd {start|stop|restart|status|condrestart}" exit 1 ;; esac exit $RETVAL openssh-7.2p2/contrib/redhat/sshd.pam010064400017500001750000000004251267006270000160220ustar00djmdjm#%PAM-1.0 auth required pam_stack.so service=system-auth account required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth openssh-7.2p2/contrib/redhat/sshd.pam.old010064400017500001750000000006321267006270000165770ustar00djmdjm#%PAM-1.0 auth required /lib/security/pam_pwdb.so shadow nodelay auth required /lib/security/pam_nologin.so account required /lib/security/pam_pwdb.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_pwdb.so shadow nullok use_authtok session required /lib/security/pam_pwdb.so session required /lib/security/pam_limits.so openssh-7.2p2/contrib/solaris004075500017500001750000000000001267006270000145125ustar00djmdjmopenssh-7.2p2/contrib/solaris/README010064400017500001750000000024461267006270000154540ustar00djmdjmThe following is a new package build script for Solaris. This is being introduced into OpenSSH 3.0 and above in hopes of simplifying the build process. As of 3.1p2 the script should work on all platforms that have SVR4 style package tools. The build process is called a 'dummy install'.. Which means the software does a "make install-nokeys DESTDIR=[fakeroot]". This way all manpages should be handled correctly and key are defered until the first time the sshd is started. Directions: 1. make -F Makefile.in distprep (Only if you are getting from the CVS tree) 2. ./configure --with-pam [..any other options you want..] 3. look at the top of buildpkg.sh for the configurable options and put any changes you want in openssh-config.local. Additional customizations can be done to the build process by creating one or more of the following scripts that will be sourced by buildpkg.sh. pkg_post_make_install_fixes.sh pkg-post-prototype-edit.sh pkg-preinstall.local pkg-postinstall.local pkg-preremove.local pkg-postremove.local pkg-request.local 4. Run "make package" If all goes well you should have a solaris package ready to be installed. If you have any problems with this script please post them to openssh-unix-dev@mindrot.org and I will try to assist you as best as I can. - Ben Lindstrom openssh-7.2p2/contrib/ssh-copy-id010064400017500001750000000241701267006270000152000ustar00djmdjm#!/bin/sh # Copyright (c) 1999-2013 Philip Hands # 2013 Martin Kletzander # 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= # 2010 Eric Moret # 2009 Xr # 2007 Justin Pryzby # 2004 Reini Urban # 2003 Colin Watson # 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. # Shell script to install your public key(s) on a remote machine # See the ssh-copy-id(1) man page for details # check that we have something mildly sane as our shell, or try to find something better if false ^ printf "%s: WARNING: ancient shell, hunting for a more modern one... " "$0" then SANE_SH=${SANE_SH:-/usr/bin/ksh} if printf 'true ^ false\n' | "$SANE_SH" then printf "'%s' seems viable.\n" "$SANE_SH" exec "$SANE_SH" "$0" "$@" else cat <<-EOF oh dear. If you have a more recent shell available, that supports \$(...) etc. please try setting the environment variable SANE_SH to the path of that shell, and then retry running this script. If that works, please report a bug describing your setup, and the shell you used to make it work. EOF printf "%s: ERROR: Less dimwitted shell required.\n" "$0" exit 1 fi fi DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" usage () { printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 printf '\t-n: dry run -- no keys are actually copied\n' >&2 printf '\t-h|-?: print this help\n' >&2 exit 1 } # escape any single quotes in an argument quote() { printf "%s\n" "$1" | sed -e "s/'/'\\\\''/g" } use_id_file() { local L_ID_FILE="$1" if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then PUB_ID_FILE="$L_ID_FILE" else PUB_ID_FILE="$L_ID_FILE.pub" fi [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) # check that the files are readable for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do ErrMSG=$( { : < "$f" ; } 2>&1 ) || { local L_PRIVMSG="" [ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)" printf "\n%s: ERROR: failed to open ID file '%s': %s\n" "$0" "$f" "$(printf "%s\n%s\n" "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" exit 1 } done printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 GET_ID="cat \"$PUB_ID_FILE\"" } if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then GET_ID="ssh-add -L" fi while test "$#" -gt 0 do [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { printf "\n%s: ERROR: -i option must not be specified more than once\n\n" "$0" usage } OPT= OPTARG= # implement something like getopt to avoid Solaris pain case "$1" in -i?*|-o?*|-p?*) OPT="$(printf -- "$1"|cut -c1-2)" OPTARG="$(printf -- "$1"|cut -c3-)" shift ;; -o|-p) OPT="$1" OPTARG="$2" shift 2 ;; -i) OPT="$1" test "$#" -le 2 || expr "$2" : "[-]" >/dev/null || { OPTARG="$2" shift } shift ;; -f|-n|-h|-\?) OPT="$1" OPTARG= shift ;; --) shift while test "$#" -gt 0 do SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" shift done break ;; -*) printf "\n%s: ERROR: invalid option (%s)\n\n" "$0" "$1" usage ;; *) SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" shift continue ;; esac case "$OPT" in -i) SEEN_OPT_I="yes" use_id_file "${OPTARG:-$DEFAULT_PUB_ID_FILE}" ;; -o|-p) SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" ;; -f) FORCED=1 ;; -n) DRY_RUN=1 ;; -h|-\?) usage ;; esac done eval set -- "$SAVEARGS" if [ $# = 0 ] ; then usage fi if [ $# != 1 ] ; then printf '%s: ERROR: Too many arguments. Expecting a target hostname, got: %s\n\n' "$0" "$SAVEARGS" >&2 usage fi # drop trailing colon USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//') # tack the hostname onto SSH_OPTS SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'" # and populate "$@" for later use (only way to get proper quoting of options) eval set -- "$SSH_OPTS" if [ -z "$(eval $GET_ID)" ] && [ -r "${PUB_ID_FILE:=$DEFAULT_PUB_ID_FILE}" ] ; then use_id_file "$PUB_ID_FILE" fi if [ -z "$(eval $GET_ID)" ] ; then printf '%s: ERROR: No identities found\n' "$0" >&2 exit 1 fi # populate_new_ids() uses several global variables ($USER_HOST, $SSH_OPTS ...) # and has the side effect of setting $NEW_IDS populate_new_ids() { local L_SUCCESS="$1" if [ "$FORCED" ] ; then NEW_IDS=$(eval $GET_ID) return fi # repopulate "$@" inside this function eval set -- "$SSH_OPTS" umask 0177 local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then printf '%s: ERROR: mktemp failed\n' "$0" >&2 exit 1 fi local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" trap "$L_CLEANUP" EXIT TERM INT QUIT printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 NEW_IDS=$( eval $GET_ID | { while read ID || [ "$ID" ] ; do printf '%s\n' "$ID" > "$L_TMP_ID_FILE" # the next line assumes $PRIV_ID_FILE only set if using a single id file - this # assumption will break if we implement the possibility of multiple -i options. # The point being that if file based, ssh needs the private key, which it cannot # find if only given the contents of the .pub file in an unrelated tmpfile ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ -o ControlPath=none \ -o LogLevel=INFO \ -o PreferredAuthentications=publickey \ -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr $L_TMP_ID_FILE else grep 'Permission denied' $L_TMP_ID_FILE.stderr >/dev/null || { sed -e 's/^/ERROR: /' <$L_TMP_ID_FILE.stderr >$L_TMP_ID_FILE cat >/dev/null #consume the other keys, causing loop to end } fi cat $L_TMP_ID_FILE done } ) eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 exit 1 fi if [ -z "$NEW_IDS" ] ; then printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 exit 0 fi printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 } REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 | sed -ne 's/.*remote software version //p') case "$REMOTE_VERSION" in NetScreen*) populate_new_ids 1 for KEY in $(printf "%s" "$NEW_IDS" | cut -d' ' -f2) ; do KEY_NO=$(($KEY_NO + 1)) printf "%s\n" "$KEY" | grep ssh-dss >/dev/null || { printf '%s: WARNING: Non-dsa key (#%d) skipped (NetScreen only supports DSA keys)\n' "$0" "$KEY_NO" >&2 continue } [ "$DRY_RUN" ] || printf 'set ssh pka-dsa key %s\nsave\nexit\n' "$KEY" | ssh -T "$@" >/dev/null 2>&1 if [ $? = 255 ] ; then printf '%s: ERROR: installation of key #%d failed (please report a bug describing what caused this, so that we can make this message useful)\n' "$0" "$KEY_NO" >&2 else ADDED=$(($ADDED + 1)) fi done if [ -z "$ADDED" ] ; then exit 1 fi ;; *) # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect populate_new_ids 0 # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh. [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ || exit 1 ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) ;; esac if [ "$DRY_RUN" ] ; then cat <<-EOF =-=-=-=-=-=-=-= Would have added the following key(s): $NEW_IDS =-=-=-=-=-=-=-= EOF else cat <<-EOF Number of key(s) added: $ADDED Now try logging into the machine, with: "ssh $SSH_OPTS" and check to make sure that only the key(s) you wanted were added. EOF fi # =-=-=-= openssh-7.2p2/contrib/ssh-copy-id.1010064400017500001750000000146311267006270000153400ustar00djmdjm.ig \" -*- nroff -*- Copyright (c) 1999-2013 hands.com Ltd. 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. .. .Dd $Mdocdate: June 17 2010 $ .Dt SSH-COPY-ID 1 .Os .Sh NAME .Nm ssh-copy-id .Nd use locally available keys to authorise logins on a remote machine .Sh SYNOPSIS .Nm .Op Fl f .Op Fl n .Op Fl i Op Ar identity_file .Op Fl p Ar port .Op Fl o Ar ssh_option .Op Ar user Ns @ Ns .Ar hostname .Nm .Fl h | Fl ? .br .Sh DESCRIPTION .Nm is a script that uses .Xr ssh 1 to log into a remote machine (presumably using a login password, so password authentication should be enabled, unless you've done some clever use of multiple identities). It assembles a list of one or more fingerprints (as described below) and tries to log in with each key, to see if any of them are already installed (of course, if you are not using .Xr ssh-agent 1 this may result in you being repeatedly prompted for pass-phrases). It then assembles a list of those that failed to log in, and using ssh, enables logins with those keys on the remote server. By default it adds the keys by appending them to the remote user's .Pa ~/.ssh/authorized_keys (creating the file, and directory, if necessary). It is also capable of detecting if the remote system is a NetScreen, and using its .Ql set ssh pka-dsa key ... command instead. .Pp The options are as follows: .Bl -tag -width Ds .It Fl i Ar identity_file Use only the key(s) contained in .Ar identity_file (rather than looking for identities via .Xr ssh-add 1 or in the .Ic default_ID_file ) . If the filename does not end in .Pa .pub this is added. If the filename is omitted, the .Ic default_ID_file is used. .Pp Note that this can be used to ensure that the keys copied have the comment one prefers and/or extra options applied, by ensuring that the key file has these set as preferred before the copy is attempted. .It Fl f Forced mode: doesn't check if the keys are present on the remote server. This means that it does not need the private key. Of course, this can result in more than one copy of the key being installed on the remote system. .It Fl n do a dry-run. Instead of installing keys on the remote system simply prints the key(s) that would have been installed. .It Fl h , Fl ? Print Usage summary .It Fl p Ar port , Fl o Ar ssh_option These two options are simply passed through untouched, along with their argument, to allow one to set the port or other .Xr ssh 1 options, respectively. .Pp Rather than specifying these as command line options, it is often better to use (per-host) settings in .Xr ssh 1 Ns 's configuration file: .Xr ssh_config 5 . .El .Pp Default behaviour without .Fl i , is to check if .Ql ssh-add -L provides any output, and if so those keys are used. Note that this results in the comment on the key being the filename that was given to .Xr ssh-add 1 when the key was loaded into your .Xr ssh-agent 1 rather than the comment contained in that file, which is a bit of a shame. Otherwise, if .Xr ssh-add 1 provides no keys contents of the .Ic default_ID_file will be used. .Pp The .Ic default_ID_file is the most recent file that matches: .Pa ~/.ssh/id*.pub , (excluding those that match .Pa ~/.ssh/*-cert.pub ) so if you create a key that is not the one you want .Nm to use, just use .Xr touch 1 on your preferred key's .Pa .pub file to reinstate it as the most recent. .Pp .Sh EXAMPLES If you have already installed keys from one system on a lot of remote hosts, and you then create a new key, on a new client machine, say, it can be difficult to keep track of which systems on which you've installed the new key. One way of dealing with this is to load both the new key and old key(s) into your .Xr ssh-agent 1 . Load the new key first, without the .Fl c option, then load one or more old keys into the agent, possibly by ssh-ing to the client machine that has that old key, using the .Fl A option to allow agent forwarding: .Pp .D1 user@newclient$ ssh-add .D1 user@newclient$ ssh -A old.client .D1 user@oldl$ ssh-add -c .D1 No ... prompt for pass-phrase ... .D1 user@old$ logoff .D1 user@newclient$ ssh someserver .Pp now, if the new key is installed on the server, you'll be allowed in unprompted, whereas if you only have the old key(s) enabled, you'll be asked for confirmation, which is your cue to log back out and run .Pp .D1 user@newclient$ ssh-copy-id -i someserver .Pp The reason you might want to specify the -i option in this case is to ensure that the comment on the installed key is the one from the .Pa .pub file, rather than just the filename that was loaded into you agent. It also ensures that only the id you intended is installed, rather than all the keys that you have in your .Xr ssh-agent 1 . Of course, you can specify another id, or use the contents of the .Xr ssh-agent 1 as you prefer. .Pp Having mentioned .Xr ssh-add 1 Ns 's .Fl c option, you might consider using this whenever using agent forwarding to avoid your key being hijacked, but it is much better to instead use .Xr ssh 1 Ns 's .Ar ProxyCommand and .Fl W option, to bounce through remote servers while always doing direct end-to-end authentication. This way the middle hop(s) don't get access to your .Xr ssh-agent 1 . A web search for .Ql ssh proxycommand nc should prove enlightening (N.B. the modern approach is to use the .Fl W option, rather than .Xr nc 1 ) . .Sh "SEE ALSO" .Xr ssh 1 , .Xr ssh-agent 1 , .Xr sshd 8 openssh-7.2p2/contrib/sshd.pam.freebsd010064400017500001750000000002671267006270000161700ustar00djmdjmsshd auth required pam_unix.so try_first_pass sshd account required pam_unix.so sshd password required pam_permit.so sshd session required pam_permit.so openssh-7.2p2/contrib/sshd.pam.generic010064400017500001750000000006321267006270000161660ustar00djmdjm#%PAM-1.0 auth required /lib/security/pam_unix.so shadow nodelay account required /lib/security/pam_nologin.so account required /lib/security/pam_unix.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_unix.so shadow nullok use_authtok session required /lib/security/pam_unix.so session required /lib/security/pam_limits.so openssh-7.2p2/contrib/suse004075500017500001750000000000001267006270000140155ustar00djmdjmopenssh-7.2p2/contrib/suse/openssh.spec010064400017500001750000000211471267006270000164310ustar00djmdjm# Default values for additional components %define build_x11_askpass 1 # Define the UID/GID to use for privilege separation %define sshd_gid 65 %define sshd_uid 71 # The version of x11-ssh-askpass to use %define xversion 1.2.4.1 # Allow the ability to override defaults with -D skip_xxx=1 %{?skip_x11_askpass:%define build_x11_askpass 0} Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh Version: 7.2p2 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz Source1: x11-ssh-askpass-%{xversion}.tar.gz License: BSD Group: Productivity/Networking/SSH BuildRoot: %{_tmppath}/openssh-%{version}-buildroot PreReq: openssl Obsoletes: ssh Provides: ssh # # (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) # building prerequisites -- stuff for # OpenSSL (openssl-devel), # and Gnome (glibdev, gtkdev, and gnlibsd) # BuildPrereq: openssl BuildPrereq: zlib-devel #BuildPrereq: glibdev #BuildPrereq: gtkdev #BuildPrereq: gnlibsd %package askpass Summary: A passphrase dialog for OpenSSH and the X window System. Group: Productivity/Networking/SSH Requires: openssh = %{version} Obsoletes: ssh-extras Provides: openssh:${_libdir}/ssh/ssh-askpass %if %{build_x11_askpass} BuildPrereq: XFree86-devel %endif %description Ssh (Secure Shell) is a program for logging into a remote machine and for executing commands in a remote machine. It is intended to replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections and arbitrary TCP/IP ports can also be forwarded over the secure channel. OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it up to date in terms of security and features, as well as removing all patented algorithms to seperate libraries (OpenSSL). This package includes all files necessary for both the OpenSSH client and server. %description askpass Ssh (Secure Shell) is a program for logging into a remote machine and for executing commands in a remote machine. It is intended to replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections and arbitrary TCP/IP ports can also be forwarded over the secure channel. OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it up to date in terms of security and features, as well as removing all patented algorithms to seperate libraries (OpenSSL). This package contains an X Window System passphrase dialog for OpenSSH. %changelog * Wed Oct 26 2005 Iain Morgan - Removed accidental inclusion of --without-zlib-version-check * Tue Oct 25 2005 Iain Morgan - Overhaul to deal with newer versions of SuSE and OpenSSH * Mon Jun 12 2000 Damien Miller - Glob manpages to catch compressed files * Wed Mar 15 2000 Damien Miller - Updated for new location - Updated for new gnome-ssh-askpass build * Sun Dec 26 1999 Chris Saia - Made symlink to gnome-ssh-askpass called ssh-askpass * Wed Nov 24 1999 Chris Saia - Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into his released tarfile - Changed permissions on ssh_config in the install procedure to 644 from 600 even though it was correct in the %files section and thus right in the RPMs - Postinstall script for the server now only prints "Generating SSH host key..." if we need to actually do this, in order to eliminate a confusing message if an SSH host key is already in place - Marked all manual pages as %doc(umentation) * Mon Nov 22 1999 Chris Saia - Added flag to configure daemon with TCP Wrappers support - Added building prerequisites (works in RPM 3.0 and newer) * Thu Nov 18 1999 Chris Saia - Made this package correct for SuSE. - Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly with SuSE, and lib_pwdb.so isn't installed by default. * Mon Nov 15 1999 Damien Miller - Split subpackages further based on patch from jim knoble * Sat Nov 13 1999 Damien Miller - Added 'Obsoletes' directives * Tue Nov 09 1999 Damien Miller - Use make install - Subpackages * Mon Nov 08 1999 Damien Miller - Added links for slogin - Fixed perms on manpages * Sat Oct 30 1999 Damien Miller - Renamed init script * Fri Oct 29 1999 Damien Miller - Back to old binary names * Thu Oct 28 1999 Damien Miller - Use autoconf - New binary names * Wed Oct 27 1999 Damien Miller - Initial RPMification, based on Jan "Yenya" Kasprzak's spec. %prep %if %{build_x11_askpass} %setup -q -a 1 %else %setup -q %endif %build CFLAGS="$RPM_OPT_FLAGS" \ %configure --prefix=/usr \ --sysconfdir=%{_sysconfdir}/ssh \ --mandir=%{_mandir} \ --with-privsep-path=/var/lib/empty \ --with-pam \ --libexecdir=%{_libdir}/ssh make %if %{build_x11_askpass} cd x11-ssh-askpass-%{xversion} %configure --mandir=/usr/X11R6/man \ --libexecdir=%{_libdir}/ssh xmkmf -a make cd .. %endif %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT/ install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/init.d/ install -d $RPM_BUILD_ROOT/var/adm/fillup-templates install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/etc/init.d/sshd install -m744 contrib/suse/sysconfig.ssh \ $RPM_BUILD_ROOT/var/adm/fillup-templates %if %{build_x11_askpass} cd x11-ssh-askpass-%{xversion} make install install.man BINDIR=%{_libdir}/ssh DESTDIR=$RPM_BUILD_ROOT/ rm -f $RPM_BUILD_ROOT/usr/share/Ssh.bin %endif %clean rm -rf $RPM_BUILD_ROOT %pre /usr/sbin/groupadd -g %{sshd_gid} -o -r sshd 2> /dev/null || : /usr/sbin/useradd -r -o -g sshd -u %{sshd_uid} -s /bin/false -c "SSH Privilege Separation User" -d /var/lib/sshd sshd 2> /dev/null || : %post /usr/bin/ssh-keygen -A %{fillup_and_insserv -n -y ssh sshd} %run_permissions %verifyscript %verify_permissions -e /etc/ssh/sshd_config -e /etc/ssh/ssh_config -e /usr/bin/ssh %preun %stop_on_removal sshd %postun %restart_on_update sshd %{insserv_cleanup} %files %defattr(-,root,root) %doc ChangeLog OVERVIEW README* PROTOCOL* %doc TODO CREDITS LICENCE %attr(0755,root,root) %dir %{_sysconfdir}/ssh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli %attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd %attr(0755,root,root) %config /etc/init.d/sshd %attr(0755,root,root) %{_bindir}/ssh-keygen %attr(0755,root,root) %{_bindir}/scp %attr(0755,root,root) %{_bindir}/ssh %attr(-,root,root) %{_bindir}/slogin %attr(0755,root,root) %{_bindir}/ssh-agent %attr(0755,root,root) %{_bindir}/ssh-add %attr(0755,root,root) %{_bindir}/ssh-keyscan %attr(0755,root,root) %{_bindir}/sftp %attr(0755,root,root) %{_sbindir}/sshd %attr(0755,root,root) %dir %{_libdir}/ssh %attr(0755,root,root) %{_libdir}/ssh/sftp-server %attr(4711,root,root) %{_libdir}/ssh/ssh-keysign %attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper %attr(0644,root,root) %doc %{_mandir}/man1/scp.1* %attr(0644,root,root) %doc %{_mandir}/man1/sftp.1* %attr(-,root,root) %doc %{_mandir}/man1/slogin.1* %attr(0644,root,root) %doc %{_mandir}/man1/ssh.1* %attr(0644,root,root) %doc %{_mandir}/man1/ssh-add.1* %attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1* %attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1* %attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1* %attr(0644,root,root) %doc %{_mandir}/man5/moduli.5* %attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5* %attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5* %attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8* %attr(0644,root,root) %doc %{_mandir}/man8/ssh-keysign.8* %attr(0644,root,root) %doc %{_mandir}/man8/ssh-pkcs11-helper.8* %attr(0644,root,root) %doc %{_mandir}/man8/sshd.8* %attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh %if %{build_x11_askpass} %files askpass %defattr(-,root,root) %doc x11-ssh-askpass-%{xversion}/README %doc x11-ssh-askpass-%{xversion}/ChangeLog %doc x11-ssh-askpass-%{xversion}/SshAskpass*.ad %attr(0755,root,root) %{_libdir}/ssh/ssh-askpass %attr(0755,root,root) %{_libdir}/ssh/x11-ssh-askpass %attr(0644,root,root) %doc /usr/X11R6/man/man1/ssh-askpass.1x* %attr(0644,root,root) %doc /usr/X11R6/man/man1/x11-ssh-askpass.1x* %attr(0644,root,root) %config /usr/X11R6/lib/X11/app-defaults/SshAskpass %endif openssh-7.2p2/contrib/suse/rc.config.sshd010064400017500001750000000000751267006270000166260ustar00djmdjm# # Start the Secure Shell (SSH) Daemon? # START_SSHD="yes" openssh-7.2p2/contrib/suse/rc.sshd010064400017500001750000000061421267006270000153630ustar00djmdjm#! /bin/sh # Copyright (c) 1995-2000 SuSE GmbH Nuernberg, Germany. # # Author: Jiri Smid # # /etc/init.d/sshd # # and symbolic its link # # /usr/sbin/rcsshd # ### BEGIN INIT INFO # Provides: sshd # Required-Start: $network $remote_fs # Required-Stop: $network $remote_fs # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Description: Start the sshd daemon ### END INIT INFO SSHD_BIN=/usr/sbin/sshd test -x $SSHD_BIN || exit 5 SSHD_SYSCONFIG=/etc/sysconfig/ssh test -r $SSHD_SYSCONFIG || exit 6 . $SSHD_SYSCONFIG SSHD_PIDFILE=/var/run/sshd.init.pid . /etc/rc.status # Shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status # First reset status of this service rc_reset case "$1" in start) # Generate any missing host keys ssh-keygen -A echo -n "Starting SSH daemon" ## Start daemon with startproc(8). If this fails ## the echo return value is set appropriate. startproc -f -p $SSHD_PIDFILE $SSHD_BIN $SSHD_OPTS -o "PidFile=$SSHD_PIDFILE" # Remember status and be verbose rc_status -v ;; stop) echo -n "Shutting down SSH daemon" ## Stop daemon with killproc(8) and if this fails ## set echo the echo return value. killproc -p $SSHD_PIDFILE -TERM $SSHD_BIN # Remember status and be verbose rc_status -v ;; try-restart) ## Stop the service and if this succeeds (i.e. the ## service was running before), start it again. $0 status >/dev/null && $0 restart # Remember status and be quiet rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop $0 start # Remember status and be quiet rc_status ;; force-reload|reload) ## Signal the daemon to reload its config. Most daemons ## do this on signal 1 (SIGHUP). echo -n "Reload service sshd" killproc -p $SSHD_PIDFILE -HUP $SSHD_BIN rc_status -v ;; status) echo -n "Checking for service sshd " ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. # Status has a slightly different for the status command: # 0 - service running # 1 - service dead, but /var/run/ pid file exists # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running checkproc -p $SSHD_PIDFILE $SSHD_BIN rc_status -v ;; probe) ## Optional: Probe for the necessity of a reload, ## give out the argument which is required for a reload. test /etc/ssh/sshd_config -nt $SSHD_PIDFILE && echo reload ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}" exit 1 ;; esac rc_exit openssh-7.2p2/contrib/suse/sysconfig.ssh010064400017500001750000000002421267006270000166120ustar00djmdjm## Path: Network/Remote access/SSH ## Description: SSH server settings ## Type: string ## Default: "" ## ServiceRestart: sshd # # Options for sshd # SSHD_OPTS="" openssh-7.2p2/channels.h010064400017500001750000000272171267006270000134270ustar00djmdjm/* $OpenBSD: channels.h,v 1.118 2015/07/01 02:26:31 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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_MUX_LISTENER 15 /* Listener for mux conn. */ #define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */ #define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */ #define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */ #define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */ #define SSH_CHANNEL_MAX_TYPE 20 #define CHANNEL_CANCEL_PORT_STATIC -1 struct Channel; typedef struct Channel Channel; typedef void channel_open_fn(int, int, void *); typedef void channel_callback_fn(int, void *); typedef int channel_infilter_fn(struct Channel *, char *, int); typedef void channel_filter_cleanup_fn(int, void *); typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); /* Channel success/failure callbacks */ typedef void channel_confirm_cb(int, struct Channel *, void *); typedef void channel_confirm_abandon_cb(struct Channel *, void *); struct channel_confirm { TAILQ_ENTRY(channel_confirm) entry; channel_confirm_cb *cb; channel_confirm_abandon_cb *abandon_cb; void *ctx; }; TAILQ_HEAD(channel_confirms, channel_confirm); /* Context for non-blocking connects */ struct channel_connect { char *host; int port; struct addrinfo *ai, *aitop; }; /* Callbacks for mux channels back into client-specific code */ typedef int mux_callback_fn(struct Channel *); 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_chan; /* control channel (multiplexed connections) */ int isatty; /* rfd is a tty */ #ifdef _AIX int wfd_isatty; /* wfd is a tty */ #endif int client_tty; /* (client) TTY has been requested */ int force_drain; /* force close on iEOF */ time_t notbefore; /* Pause IO until deadline (time_t) */ int delayed; /* post-select handlers for newly created * channels are delayed until the first call * to a matching pre-select handler. * this way post-select handlers are not * accidentally called if a FD gets reused */ 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; /* path for unix domain sockets, or host name for forwards */ int listening_port; /* port being listened for forwards */ char *listening_addr; /* addr 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_open_fn *open_confirm; void *open_confirm_ctx; channel_callback_fn *detach_user; int detach_close; struct channel_confirms status_confirms; /* filter */ channel_infilter_fn *input_filter; channel_outfilter_fn *output_filter; void *filter_ctx; channel_filter_cleanup_fn *filter_cleanup; /* keep boundaries */ int datagram; /* non-blocking connect */ struct channel_connect connect_ctx; /* multiplexing protocol hook, called for each packet received */ mux_callback_fn *mux_rcb; void *mux_ctx; int mux_pause; }; #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 (64*CHAN_SES_PACKET_DEFAULT) #define CHAN_TCP_PACKET_DEFAULT (32*1024) #define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT) #define CHAN_X11_PACKET_DEFAULT (16*1024) #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) /* 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_LOCAL 0x10 #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, 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_open_confirm(int, channel_open_fn *, void *); void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); void channel_register_status_confirm(int, channel_confirm_cb *, channel_confirm_abandon_cb *, void *); void channel_cancel_cleanup(int); int channel_close_fd(int *); void channel_send_window_changes(void); /* protocol handler */ int channel_input_close(int, u_int32_t, void *); int channel_input_close_confirmation(int, u_int32_t, void *); int channel_input_data(int, u_int32_t, void *); int channel_input_extended_data(int, u_int32_t, void *); int channel_input_ieof(int, u_int32_t, void *); int channel_input_oclose(int, u_int32_t, void *); int channel_input_open_confirmation(int, u_int32_t, void *); int channel_input_open_failure(int, u_int32_t, void *); int channel_input_port_open(int, u_int32_t, void *); int channel_input_window_adjust(int, u_int32_t, void *); int channel_input_status_confirm(int, u_int32_t, void *); /* file descriptor handling (read/write) */ void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, time_t*, 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 */ struct Forward; struct ForwardOptions; 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_disable_adm_local_opens(void); void channel_update_permitted_opens(int, int); void channel_clear_permitted_opens(void); void channel_clear_adm_permitted_opens(void); void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, struct ForwardOptions *); Channel *channel_connect_to_port(const char *, u_short, char *, char *); Channel *channel_connect_to_path(const char *, char *, char *); Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); Channel *channel_connect_by_listen_address(const char *, u_short, char *, char *); Channel *channel_connect_by_listen_path(const char *, char *, char *); int channel_request_remote_forwarding(struct Forward *); int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *); int channel_request_rforward_cancel(struct Forward *); int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *); int channel_cancel_rport_listener(struct Forward *); int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *); int permitopen_port(const char *); /* x11 forwarding */ void channel_set_x11_refuse_time(u_int); int x11_connect_display(void); int x11_create_display_inet(int, int, int, u_int *, int **); int x11_input_open(int, u_int32_t, void *); void x11_request_forwarding_with_spoofing(int, const char *, const char *, const char *, int); int 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_rcvd_eow(Channel *); /* SSH2-only */ 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 openssh-7.2p2/cipher-3des1.c010064400017500001750000000103711267006270000140070ustar00djmdjm/* $OpenBSD: cipher-3des1.c,v 1.12 2015/01/14 10:24:42 markus Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * 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 #include #include #include "ssherr.h" /* * 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); int 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) { if ((c = calloc(1, sizeof(*c))) == NULL) return 0; EVP_CIPHER_CTX_set_app_data(ctx, c); } if (key == NULL) return 1; if (enc == -1) enc = ctx->encrypt; k1 = k2 = k3 = (u_char *) key; k2 += 8; if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { if (enc) k3 += 16; else k1 += 16; } EVP_CIPHER_CTX_init(&c->k1); EVP_CIPHER_CTX_init(&c->k2); EVP_CIPHER_CTX_init(&c->k3); if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { explicit_bzero(c, sizeof(*c)); free(c); EVP_CIPHER_CTX_set_app_data(ctx, NULL); return 0; } return 1; } static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, size_t len) { struct ssh1_3des_ctx *c; if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) return 0; if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || EVP_Cipher(&c->k2, dest, dest, len) == 0 || EVP_Cipher(&c->k3, dest, dest, len) == 0) return 0; return 1; } static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) { struct ssh1_3des_ctx *c; if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { EVP_CIPHER_CTX_cleanup(&c->k1); EVP_CIPHER_CTX_cleanup(&c->k2); EVP_CIPHER_CTX_cleanup(&c->k3); explicit_bzero(c, sizeof(*c)); free(c); EVP_CIPHER_CTX_set_app_data(ctx, NULL); } return 1; } int ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) { struct ssh1_3des_ctx *c; if (len != 24) return SSH_ERR_INVALID_ARGUMENT; if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) return SSH_ERR_INTERNAL_ERROR; if (doset) { memcpy(c->k1.iv, iv, 8); memcpy(c->k2.iv, iv + 8, 8); memcpy(c->k3.iv, iv + 16, 8); } else { memcpy(iv, c->k1.iv, 8); memcpy(iv + 8, c->k2.iv, 8); memcpy(iv + 16, c->k3.iv, 8); } return 0; } const EVP_CIPHER * evp_ssh1_3des(void) { static EVP_CIPHER ssh1_3des; memset(&ssh1_3des, 0, sizeof(ssh1_3des)); ssh1_3des.nid = NID_undef; ssh1_3des.block_size = 8; ssh1_3des.iv_len = 0; ssh1_3des.key_len = 16; ssh1_3des.init = ssh1_3des_init; ssh1_3des.cleanup = ssh1_3des_cleanup; ssh1_3des.do_cipher = ssh1_3des_cbc; ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; return &ssh1_3des; } openssh-7.2p2/cipher-aes.c010064400017500001750000000110531267006270000136360ustar00djmdjm/* * 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 #include #include #include #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]; }; 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, LIBCRYPTO_EVP_INL_TYPE 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)); free(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 */ openssh-7.2p2/cipher-aesctr.c010064400017500001750000000040741267006270000143540ustar00djmdjm/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #include #ifndef WITH_OPENSSL #include "cipher-aesctr.h" /* * 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 inline void aesctr_inc(u8 *ctr, u32 len) { ssize_t i; #ifndef CONSTANT_TIME_INCREMENT for (i = len - 1; i >= 0; i--) if (++ctr[i]) /* continue on overflow */ return; #else u8 x, add = 1; for (i = len - 1; i >= 0; i--) { ctr[i] += add; /* constant time for: x = ctr[i] ? 1 : 0 */ x = ctr[i]; x = (x | (x >> 4)) & 0xf; x = (x | (x >> 2)) & 0x3; x = (x | (x >> 1)) & 0x1; add *= (x^1); } #endif } void aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits) { x->rounds = rijndaelKeySetupEnc(x->ek, k, kbits); } void aesctr_ivsetup(aesctr_ctx *x,const u8 *iv) { memcpy(x->ctr, iv, AES_BLOCK_SIZE); } void aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes) { u32 n = 0; u8 buf[AES_BLOCK_SIZE]; while ((bytes--) > 0) { if (n == 0) { rijndaelEncrypt(x->ek, x->rounds, x->ctr, buf); aesctr_inc(x->ctr, AES_BLOCK_SIZE); } *(c++) = *(m++) ^ buf[n]; n = (n + 1) % AES_BLOCK_SIZE; } } #endif /* !WITH_OPENSSL */ openssh-7.2p2/cipher-aesctr.h010064400017500001750000000024631267006270000143610ustar00djmdjm/* $OpenBSD: cipher-aesctr.h,v 1.1 2014/04/29 15:39:33 markus Exp $ */ /* * Copyright (c) 2014 Markus Friedl * * 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 OPENSSH_AESCTR_H #define OPENSSH_AESCTR_H #include "rijndael.h" #define AES_BLOCK_SIZE 16 typedef struct aesctr_ctx { int rounds; /* keylen-dependent #rounds */ u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ u8 ctr[AES_BLOCK_SIZE]; /* counter */ } aesctr_ctx; void aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits); void aesctr_ivsetup(aesctr_ctx *x,const u8 *iv); void aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes); #endif openssh-7.2p2/cipher-bf1.c010064400017500001750000000053051267006270000135410ustar00djmdjm/* $OpenBSD: cipher-bf1.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * 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 WITH_OPENSSL #include #include #include #include #include "openbsd-compat/openssl-compat.h" /* * 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 *, LIBCRYPTO_EVP_INL_TYPE) = NULL; static int bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, LIBCRYPTO_EVP_INL_TYPE 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); } #endif /* WITH_OPENSSL */ openssh-7.2p2/cipher-chachapoly.c010064400017500001750000000073511267006270000152070ustar00djmdjm/* * Copyright (c) 2013 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* $OpenBSD: cipher-chachapoly.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */ #include "includes.h" #include #include /* needed for log.h */ #include #include /* needed for misc.h */ #include "log.h" #include "sshbuf.h" #include "ssherr.h" #include "cipher-chachapoly.h" int chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen) { if (keylen != (32 + 32)) /* 2 x 256 bit keys */ return SSH_ERR_INVALID_ARGUMENT; chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256); return 0; } /* * chachapoly_crypt() operates as following: * En/decrypt with header key 'aadlen' bytes from 'src', storing result * to 'dest'. The ciphertext here is treated as additional authenticated * data for MAC calculation. * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication * tag. This tag is written on encryption and verified on decryption. */ int chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt) { u_char seqbuf[8]; const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; int r = SSH_ERR_INTERNAL_ERROR; /* * Run ChaCha20 once to generate the Poly1305 key. The IV is the * packet sequence number. */ memset(poly_key, 0, sizeof(poly_key)); POKE_U64(seqbuf, seqnr); chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); /* If decrypting, check tag before anything else */ if (!do_encrypt) { const u_char *tag = src + aadlen + len; poly1305_auth(expected_tag, src, aadlen + len, poly_key); if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { r = SSH_ERR_MAC_INVALID; goto out; } } /* Crypt additional data */ if (aadlen) { chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen); } /* Set Chacha's block counter to 1 */ chacha_ivsetup(&ctx->main_ctx, seqbuf, one); chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen, dest + aadlen, len); /* If encrypting, calculate and append tag */ if (do_encrypt) { poly1305_auth(dest + aadlen + len, dest, aadlen + len, poly_key); } r = 0; out: explicit_bzero(expected_tag, sizeof(expected_tag)); explicit_bzero(seqbuf, sizeof(seqbuf)); explicit_bzero(poly_key, sizeof(poly_key)); return r; } /* Decrypt and extract the encrypted packet length */ int chachapoly_get_length(struct chachapoly_ctx *ctx, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { u_char buf[4], seqbuf[8]; if (len < 4) return SSH_ERR_MESSAGE_INCOMPLETE; POKE_U64(seqbuf, seqnr); chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4); *plenp = PEEK_U32(buf); return 0; } openssh-7.2p2/cipher-chachapoly.h010064400017500001750000000031171267006270000152100ustar00djmdjm/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */ /* * Copyright (c) Damien Miller 2013 * * 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 CHACHA_POLY_AEAD_H #define CHACHA_POLY_AEAD_H #include #include "chacha.h" #include "poly1305.h" #define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ struct chachapoly_ctx { struct chacha_ctx main_ctx, header_ctx; }; int chachapoly_init(struct chachapoly_ctx *cpctx, const u_char *key, u_int keylen) __attribute__((__bounded__(__buffer__, 2, 3))); int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt); int chachapoly_get_length(struct chachapoly_ctx *cpctx, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) __attribute__((__bounded__(__buffer__, 4, 5))); #endif /* CHACHA_POLY_AEAD_H */ openssh-7.2p2/cipher-ctr.c010064400017500001750000000071141267006270000136610ustar00djmdjm/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */ /* * Copyright (c) 2003 Markus Friedl * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) #include #include #include #include #include "xmalloc.h" #include "log.h" /* compatibility with old or broken OpenSSL versions */ #include "openbsd-compat/openssl-compat.h" #ifndef USE_BUILTIN_RIJNDAEL #include #endif 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, size_t 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, LIBCRYPTO_EVP_INL_TYPE len) { struct ssh_aes_ctr_ctx *c; size_t 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)); free(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, size_t 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); } #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) */ openssh-7.2p2/cipher.c010064400017500001750000000416611267006270000131000ustar00djmdjm/* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include "cipher.h" #include "misc.h" #include "sshbuf.h" #include "ssherr.h" #include "digest.h" #include "openbsd-compat/openssl-compat.h" #ifdef WITH_SSH1 extern const EVP_CIPHER *evp_ssh1_bf(void); extern const EVP_CIPHER *evp_ssh1_3des(void); extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #endif struct sshcipher { char *name; int number; /* for ssh1 only */ u_int block_size; u_int key_len; u_int iv_len; /* defaults to block_size */ u_int auth_len; u_int discard_len; u_int flags; #define CFLAG_CBC (1<<0) #define CFLAG_CHACHAPOLY (1<<1) #define CFLAG_AESCTR (1<<2) #define CFLAG_NONE (1<<3) #ifdef WITH_OPENSSL const EVP_CIPHER *(*evptype)(void); #else void *ignored; #endif }; static const struct sshcipher ciphers[] = { #ifdef WITH_SSH1 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, { "rijndael-cbc@lysator.liu.se", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, # ifdef OPENSSL_HAVE_EVPGCM { "aes128-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, { "aes256-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, # endif /* OPENSSL_HAVE_EVPGCM */ #else /* WITH_OPENSSL */ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, #endif /* WITH_OPENSSL */ { "chacha20-poly1305@openssh.com", SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; /*--*/ /* Returns a comma-separated list of supported ciphers. */ char * cipher_alg_list(char sep, int auth_only) { char *tmp, *ret = NULL; size_t nlen, rlen = 0; const struct sshcipher *c; for (c = ciphers; c->name != NULL; c++) { if (c->number != SSH_CIPHER_SSH2) continue; if (auth_only && c->auth_len == 0) continue; if (ret != NULL) ret[rlen++] = sep; nlen = strlen(c->name); if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { free(ret); return NULL; } ret = tmp; memcpy(ret + rlen, c->name, nlen + 1); rlen += nlen; } return ret; } u_int cipher_blocksize(const struct sshcipher *c) { return (c->block_size); } u_int cipher_keylen(const struct sshcipher *c) { return (c->key_len); } u_int cipher_seclen(const struct sshcipher *c) { if (strcmp("3des-cbc", c->name) == 0) return 14; return cipher_keylen(c); } u_int cipher_authlen(const struct sshcipher *c) { return (c->auth_len); } u_int cipher_ivlen(const struct sshcipher *c) { /* * Default is cipher block size, except for chacha20+poly1305 that * needs no IV. XXX make iv_len == -1 default? */ return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ? c->iv_len : c->block_size; } u_int cipher_get_number(const struct sshcipher *c) { return (c->number); } u_int cipher_is_cbc(const struct sshcipher *c) { return (c->flags & CFLAG_CBC) != 0; } 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; } const struct sshcipher * cipher_by_name(const char *name) { const struct sshcipher *c; for (c = ciphers; c->name != NULL; c++) if (strcmp(c->name, name) == 0) return c; return NULL; } const struct sshcipher * cipher_by_number(int id) { const struct sshcipher *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) { const struct sshcipher *c; char *cipher_list, *cp; char *p; if (names == NULL || strcmp(names, "") == 0) return 0; if ((cipher_list = cp = strdup(names)) == NULL) return 0; 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) { free(cipher_list); return 0; } } free(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) { const struct sshcipher *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) { const struct sshcipher *c = cipher_by_number(id); return (c==NULL) ? "" : c->name; } const char * cipher_warning_message(const struct sshcipher_ctx *cc) { if (cc == NULL || cc->cipher == NULL) return NULL; if (cc->cipher->number == SSH_CIPHER_DES) return "use of DES is strongly discouraged due to " "cryptographic weaknesses"; return NULL; } int cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { #ifdef WITH_OPENSSL int ret = SSH_ERR_INTERNAL_ERROR; const EVP_CIPHER *type; int klen; u_char *junk, *discard; if (cipher->number == SSH_CIPHER_DES) { if (keylen > 8) keylen = 8; } #endif cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len || (iv != NULL && ivlen < cipher_ivlen(cipher))) return SSH_ERR_INVALID_ARGUMENT; cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { return chachapoly_init(&cc->cp_ctx, key, keylen); } #ifndef WITH_OPENSSL if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); aesctr_ivsetup(&cc->ac_ctx, iv); return 0; } if ((cc->cipher->flags & CFLAG_NONE) != 0) return 0; return SSH_ERR_INVALID_ARGUMENT; #else type = (*cipher->evptype)(); EVP_CIPHER_CTX_init(&cc->evp); if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } } if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } if (cipher->discard_len > 0) { if ((junk = malloc(cipher->discard_len)) == NULL || (discard = malloc(cipher->discard_len)) == NULL) { free(junk); ret = SSH_ERR_ALLOC_FAIL; goto bad; } ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); explicit_bzero(discard, cipher->discard_len); free(junk); free(discard); if (ret != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; bad: EVP_CIPHER_CTX_cleanup(&cc->evp); return ret; } } #endif return 0; } /* * cipher_crypt() operates as following: * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. * Theses bytes are treated as additional authenticated data for * authenticated encryption modes. * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. * This tag is written on encryption and verified on decryption. * Both 'aadlen' and 'authlen' can be set to 0. */ int cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, aadlen, authlen, cc->encrypt); } #ifndef WITH_OPENSSL if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { if (aadlen) memcpy(dest, src, aadlen); aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen, dest + aadlen, len); return 0; } if ((cc->cipher->flags & CFLAG_NONE) != 0) { memcpy(dest, src, aadlen + len); return 0; } return SSH_ERR_INVALID_ARGUMENT; #else if (authlen) { u_char lastiv[1]; if (authlen != cipher_authlen(cc->cipher)) return SSH_ERR_INVALID_ARGUMENT; /* increment IV */ if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) return SSH_ERR_LIBCRYPTO_ERROR; /* set tag on decyption */ if (!cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, (u_char *)src + aadlen + len)) return SSH_ERR_LIBCRYPTO_ERROR; } if (aadlen) { if (authlen && EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) return SSH_ERR_LIBCRYPTO_ERROR; memcpy(dest, src, aadlen); } if (len % cc->cipher->block_size) return SSH_ERR_INVALID_ARGUMENT; if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, len) < 0) return SSH_ERR_LIBCRYPTO_ERROR; if (authlen) { /* compute tag (on encrypt) or verify tag (on decrypt) */ if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) return cc->encrypt ? SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; if (cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, dest + aadlen + len)) return SSH_ERR_LIBCRYPTO_ERROR; } return 0; #endif } /* Extract the packet length, including any decryption necessary beforehand */ int cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, cp, len); if (len < 4) return SSH_ERR_MESSAGE_INCOMPLETE; *plenp = get_u32(cp); return 0; } int cipher_cleanup(struct sshcipher_ctx *cc) { if (cc == NULL || cc->cipher == NULL) return 0; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); #ifdef WITH_OPENSSL else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) return SSH_ERR_LIBCRYPTO_ERROR; #endif return 0; } /* * Selects the cipher, and keys if by computing the MD5 checksum of the * passphrase and using the resulting 16 bytes as the key. */ int cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher, const char *passphrase, int do_encrypt) { u_char digest[16]; int r = SSH_ERR_INTERNAL_ERROR; if ((r = ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), digest, sizeof(digest))) != 0) goto out; r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); out: explicit_bzero(digest, sizeof(digest)); return r; } /* * Exports an IV from the sshcipher_ctx required to export the key * state back from the unprivileged child to the privileged parent * process. */ int cipher_get_keyiv_len(const struct sshcipher_ctx *cc) { const struct sshcipher *c = cc->cipher; int ivlen = 0; if (c->number == SSH_CIPHER_3DES) ivlen = 24; else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) ivlen = 0; else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) ivlen = sizeof(cc->ac_ctx.ctr); #ifdef WITH_OPENSSL else ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); #endif /* WITH_OPENSSL */ return (ivlen); } int cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) { const struct sshcipher *c = cc->cipher; #ifdef WITH_OPENSSL int evplen; #endif if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { if (len != 0) return SSH_ERR_INVALID_ARGUMENT; return 0; } if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { if (len != sizeof(cc->ac_ctx.ctr)) return SSH_ERR_INVALID_ARGUMENT; memcpy(iv, cc->ac_ctx.ctr, len); return 0; } if ((cc->cipher->flags & CFLAG_NONE) != 0) return 0; switch (c->number) { #ifdef WITH_OPENSSL case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); if (evplen == 0) return 0; else if (evplen < 0) return SSH_ERR_LIBCRYPTO_ERROR; if ((u_int)evplen != len) return SSH_ERR_INVALID_ARGUMENT; #ifndef OPENSSL_HAVE_EVPCTR if (c->evptype == evp_aes_128_ctr) ssh_aes_ctr_iv(&cc->evp, 0, iv, len); else #endif if (cipher_authlen(c)) { if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, len, iv)) return SSH_ERR_LIBCRYPTO_ERROR; } else memcpy(iv, cc->evp.iv, len); break; #endif #ifdef WITH_SSH1 case SSH_CIPHER_3DES: return ssh1_3des_iv(&cc->evp, 0, iv, 24); #endif default: return SSH_ERR_INVALID_ARGUMENT; } return 0; } int cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) { const struct sshcipher *c = cc->cipher; #ifdef WITH_OPENSSL int evplen = 0; #endif if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return 0; if ((cc->cipher->flags & CFLAG_NONE) != 0) return 0; switch (c->number) { #ifdef WITH_OPENSSL case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); if (evplen <= 0) return SSH_ERR_LIBCRYPTO_ERROR; if (cipher_authlen(c)) { /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) return SSH_ERR_LIBCRYPTO_ERROR; } else memcpy(cc->evp.iv, iv, evplen); break; #endif #ifdef WITH_SSH1 case SSH_CIPHER_3DES: return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); #endif default: return SSH_ERR_INVALID_ARGUMENT; } return 0; } #ifdef WITH_OPENSSL #define EVP_X_STATE(evp) (evp).cipher_data #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size #endif int cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat) { #ifdef WITH_OPENSSL const struct sshcipher *c = cc->cipher; int plen = 0; if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); if (dat == NULL) return (plen); memcpy(dat, EVP_X_STATE(cc->evp), plen); } return (plen); #else return 0; #endif } void cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat) { #ifdef WITH_OPENSSL const struct sshcipher *c = cc->cipher; int plen; if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); memcpy(EVP_X_STATE(cc->evp), dat, plen); } #endif } openssh-7.2p2/cipher.h010064400017500001750000000105741267006270000131040ustar00djmdjm/* $OpenBSD: cipher.h,v 1.48 2015/07/08 19:09:25 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 #include #include "cipher-chachapoly.h" #include "cipher-aesctr.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 struct sshcipher; struct sshcipher_ctx { int plaintext; int encrypt; EVP_CIPHER_CTX evp; struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ struct aesctr_ctx ac_ctx; /* XXX union with evp? */ const struct sshcipher *cipher; }; u_int cipher_mask_ssh1(int); const struct sshcipher *cipher_by_name(const char *); const struct sshcipher *cipher_by_number(int); int cipher_number(const char *); char *cipher_name(int); const char *cipher_warning_message(const struct sshcipher_ctx *); int ciphers_valid(const char *); char *cipher_alg_list(char, int); int cipher_init(struct sshcipher_ctx *, const struct sshcipher *, const u_char *, u_int, const u_char *, u_int, int); int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, u_int, u_int, u_int); int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, const u_char *, u_int); int cipher_cleanup(struct sshcipher_ctx *); int cipher_set_key_string(struct sshcipher_ctx *, const struct sshcipher *, const char *, int); u_int cipher_blocksize(const struct sshcipher *); u_int cipher_keylen(const struct sshcipher *); u_int cipher_seclen(const struct sshcipher *); u_int cipher_authlen(const struct sshcipher *); u_int cipher_ivlen(const struct sshcipher *); u_int cipher_is_cbc(const struct sshcipher *); u_int cipher_get_number(const struct sshcipher *); int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); int cipher_get_keyiv_len(const struct sshcipher_ctx *); int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *); void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *); #endif /* CIPHER_H */ openssh-7.2p2/cleanup.c010064400017500001750000000020131267006270000132410ustar00djmdjm/* $OpenBSD: cleanup.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */ /* * Copyright (c) 2003 Markus Friedl * * 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 #include #include #include "log.h" /* default implementation */ void cleanup_exit(int i) { _exit(i); } openssh-7.2p2/clientloop.c010064400017500001750000002252171267006270000137770ustar00djmdjm/* $OpenBSD: clientloop.c,v 1.284 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * The main loop for the interactive session (client side). * * 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 Theo de Raadt. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * SSH2 support added by Markus Friedl. * 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. */ #include "includes.h" #include /* MIN MAX */ #include #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" #include "packet.h" #include "buffer.h" #include "compat.h" #include "channels.h" #include "dispatch.h" #include "key.h" #include "cipher.h" #include "kex.h" #include "myproposal.h" #include "log.h" #include "misc.h" #include "readconf.h" #include "clientloop.h" #include "sshconnect.h" #include "authfd.h" #include "atomicio.h" #include "sshpty.h" #include "match.h" #include "msg.h" #include "ssherr.h" #include "hostfile.h" /* import options */ extern Options options; /* Flag indicating that stdin should be redirected from /dev/null. */ extern int stdin_null_flag; /* Flag indicating that no shell has been requested */ extern int no_shell_flag; /* Control socket */ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ /* * Name of the host we are connecting to. This is the name given on the * command line, or the HostName specified for the user-supplied name in a * configuration file. */ extern char *host; /* * Flag to indicate that we have received a window change signal which has * not yet been processed. This will cause a message indicating the new * window size to be sent to the server a little later. This is volatile * because this is updated in a signal handler. */ static volatile sig_atomic_t received_window_change_signal = 0; static volatile sig_atomic_t received_signal = 0; /* Flag indicating whether the user's terminal is in non-blocking mode. */ static int in_non_blocking_mode = 0; /* Time when backgrounded control master using ControlPersist should exit */ static time_t control_persist_exit_time = 0; /* Common data for the client loop code. */ volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ static int escape_char1; /* Escape character. (proto1 only) */ static int escape_pending1; /* Last character was an escape (proto1 only) */ static int last_was_cr; /* Last character was a newline. */ static int exit_status; /* Used to store the command exit status. */ static int stdin_eof; /* EOF has been encountered on stderr. */ static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ static Buffer stderr_buffer; /* Buffer for stderr data. */ static u_int buffer_high; /* Soft max buffer size. */ static int connection_in; /* Connection to server (input). */ static int connection_out; /* Connection to server (output). */ static int need_rekeying; /* Set to non-zero if rekeying is requested. */ static int session_closed; /* In SSH2: login session closed. */ static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ static void client_init_dispatch(void); int session_ident = -1; /* Track escape per proto2 channel */ struct escape_filter_ctx { int escape_pending; int escape_char; }; /* Context for channel confirmation replies */ struct channel_reply_ctx { const char *request_type; int id; enum confirm_action action; }; /* Global request success/failure callbacks */ struct global_confirm { TAILQ_ENTRY(global_confirm) entry; global_confirm_cb *cb; void *ctx; int ref_count; }; TAILQ_HEAD(global_confirms, global_confirm); static struct global_confirms global_confirms = TAILQ_HEAD_INITIALIZER(global_confirms); void ssh_process_session2_setup(int, int, int, Buffer *); /* Restores stdin to blocking mode. */ static void leave_non_blocking(void) { if (in_non_blocking_mode) { unset_nonblock(fileno(stdin)); in_non_blocking_mode = 0; } } /* Puts stdin terminal in non-blocking mode. */ static void enter_non_blocking(void) { in_non_blocking_mode = 1; set_nonblock(fileno(stdin)); } /* * Signal handler for the window change signal (SIGWINCH). This just sets a * flag indicating that the window has changed. */ /*ARGSUSED */ static void window_change_handler(int sig) { received_window_change_signal = 1; signal(SIGWINCH, window_change_handler); } /* * Signal handler for signals that cause the program to terminate. These * signals must be trapped to restore terminal modes. */ /*ARGSUSED */ static void signal_handler(int sig) { received_signal = sig; quit_pending = 1; } /* * Returns current time in seconds from Jan 1, 1970 with the maximum * available resolution. */ static double get_current_time(void) { struct timeval tv; gettimeofday(&tv, NULL); return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; } /* * Sets control_persist_exit_time to the absolute time when the * backgrounded control master should exit due to expiry of the * ControlPersist timeout. Sets it to 0 if we are not a backgrounded * control master process, or if there is no ControlPersist timeout. */ static void set_control_persist_exit_time(void) { if (muxserver_sock == -1 || !options.control_persist || options.control_persist_timeout == 0) { /* not using a ControlPersist timeout */ control_persist_exit_time = 0; } else if (channel_still_open()) { /* some client connections are still open */ if (control_persist_exit_time > 0) debug2("%s: cancel scheduled exit", __func__); control_persist_exit_time = 0; } else if (control_persist_exit_time <= 0) { /* a client connection has recently closed */ control_persist_exit_time = monotime() + (time_t)options.control_persist_timeout; debug2("%s: schedule exit in %d seconds", __func__, options.control_persist_timeout); } /* else we are already counting down to the timeout */ } #define SSH_X11_VALID_DISPLAY_CHARS ":/.-_" static int client_x11_display_valid(const char *display) { size_t i, dlen; if (display == NULL) return 0; dlen = strlen(display); for (i = 0; i < dlen; i++) { if (!isalnum((u_char)display[i]) && strchr(SSH_X11_VALID_DISPLAY_CHARS, display[i]) == NULL) { debug("Invalid character '%c' in DISPLAY", display[i]); return 0; } } return 1; } #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" #define X11_TIMEOUT_SLACK 60 int client_x11_get_proto(const char *display, const char *xauth_path, u_int trusted, u_int timeout, char **_proto, char **_data) { char cmd[1024], line[512], xdisplay[512]; char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; static char proto[512], data[512]; FILE *f; int got_data = 0, generated = 0, do_unlink = 0, i, r; struct stat st; u_int now, x11_timeout_real; *_proto = proto; *_data = data; proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; if (!client_x11_display_valid(display)) { if (display != NULL) logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", display); return -1; } if (xauth_path != NULL && stat(xauth_path, &st) == -1) { debug("No xauth program."); xauth_path = NULL; } if (xauth_path != NULL) { /* * Handle FamilyLocal case where $DISPLAY does * not match an authorization entry. For this we * just try "xauth list unix:displaynum.screennum". * XXX: "localhost" match to determine FamilyLocal * is not perfect. */ if (strncmp(display, "localhost:", 10) == 0) { if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", display + 10)) < 0 || (size_t)r >= sizeof(xdisplay)) { error("%s: display name too long", __func__); return -1; } display = xdisplay; } if (trusted == 0) { /* * Generate an untrusted X11 auth cookie. * * The authentication cookie should briefly outlive * ssh's willingness to forward X11 connections to * avoid nasty fail-open behaviour in the X server. */ mktemp_proto(xauthdir, sizeof(xauthdir)); if (mkdtemp(xauthdir) == NULL) { error("%s: mkdtemp: %s", __func__, strerror(errno)); return -1; } do_unlink = 1; if ((r = snprintf(xauthfile, sizeof(xauthfile), "%s/xauthfile", xauthdir)) < 0 || (size_t)r >= sizeof(xauthfile)) { error("%s: xauthfile path too long", __func__); unlink(xauthfile); rmdir(xauthdir); return -1; } if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) x11_timeout_real = UINT_MAX; else x11_timeout_real = timeout + X11_TIMEOUT_SLACK; if ((r = snprintf(cmd, sizeof(cmd), "%s -f %s generate %s " SSH_X11_PROTO " untrusted timeout %u 2>" _PATH_DEVNULL, xauth_path, xauthfile, display, x11_timeout_real)) < 0 || (size_t)r >= sizeof(cmd)) fatal("%s: cmd too long", __func__); debug2("%s: %s", __func__, cmd); if (x11_refuse_time == 0) { now = monotime() + 1; if (UINT_MAX - timeout < now) x11_refuse_time = UINT_MAX; else x11_refuse_time = now + timeout; channel_set_x11_refuse_time(x11_refuse_time); } if (system(cmd) == 0) generated = 1; } /* * When in untrusted mode, we read the cookie only if it was * successfully generated as an untrusted one in the step * above. */ if (trusted || generated) { snprintf(cmd, sizeof(cmd), "%s %s%s list %s 2>" _PATH_DEVNULL, xauth_path, generated ? "-f " : "" , generated ? xauthfile : "", display); debug2("x11_get_proto: %s", cmd); f = popen(cmd, "r"); if (f && fgets(line, sizeof(line), f) && sscanf(line, "%*s %511s %511s", proto, data) == 2) got_data = 1; if (f) pclose(f); } } if (do_unlink) { unlink(xauthfile); rmdir(xauthdir); } /* Don't fall back to fake X11 data for untrusted forwarding */ if (!trusted && !got_data) { error("Warning: untrusted X11 forwarding setup failed: " "xauth key data not generated"); return -1; } /* * If we didn't get authentication data, just make up some * data. The forwarding code will check the validity of the * response anyway, and substitute this data. The X11 * server, however, will ignore this fake data and use * whatever authentication mechanisms it was using otherwise * for the local connection. */ if (!got_data) { u_int32_t rnd = 0; logit("Warning: No xauth data; " "using fake authentication data for X11 forwarding."); strlcpy(proto, SSH_X11_PROTO, sizeof proto); for (i = 0; i < 16; i++) { if (i % 4 == 0) rnd = arc4random(); snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rnd & 0xff); rnd >>= 8; } } return 0; } /* * This is called when the interactive is entered. This checks if there is * an EOF coming on stdin. We must check this explicitly, as select() does * not appear to wake up when redirecting from /dev/null. */ static void client_check_initial_eof_on_stdin(void) { int len; char buf[1]; /* * If standard input is to be "redirected from /dev/null", we simply * mark that we have seen an EOF and send an EOF message to the * server. Otherwise, we try to read a single character; it appears * that for some files, such /dev/null, select() never wakes up for * read for this descriptor, which means that we never get EOF. This * way we will get the EOF if stdin comes from /dev/null or similar. */ if (stdin_null_flag) { /* Fake EOF on stdin. */ debug("Sending eof."); stdin_eof = 1; packet_start(SSH_CMSG_EOF); packet_send(); } else { enter_non_blocking(); /* Check for immediate EOF on stdin. */ len = read(fileno(stdin), buf, 1); if (len == 0) { /* * EOF. Record that we have seen it and send * EOF to server. */ debug("Sending eof."); stdin_eof = 1; packet_start(SSH_CMSG_EOF); packet_send(); } else if (len > 0) { /* * Got data. We must store the data in the buffer, * and also process it as an escape character if * appropriate. */ if ((u_char) buf[0] == escape_char1) escape_pending1 = 1; else buffer_append(&stdin_buffer, buf, 1); } leave_non_blocking(); } } /* * Make packets from buffered stdin data, and buffer them for sending to the * connection. */ static void client_make_packets_from_stdin_data(void) { u_int len; /* Send buffered stdin data to the server. */ while (buffer_len(&stdin_buffer) > 0 && packet_not_very_much_data_to_write()) { len = buffer_len(&stdin_buffer); /* Keep the packets at reasonable size. */ if (len > packet_get_maxsize()) len = packet_get_maxsize(); packet_start(SSH_CMSG_STDIN_DATA); packet_put_string(buffer_ptr(&stdin_buffer), len); packet_send(); buffer_consume(&stdin_buffer, len); /* If we have a pending EOF, send it now. */ if (stdin_eof && buffer_len(&stdin_buffer) == 0) { packet_start(SSH_CMSG_EOF); packet_send(); } } } /* * Checks if the client window has changed, and sends a packet about it to * the server if so. The actual change is detected elsewhere (by a software * interrupt on Unix); this just checks the flag and sends a message if * appropriate. */ static void client_check_window_change(void) { struct winsize ws; if (! received_window_change_signal) return; /** XXX race */ received_window_change_signal = 0; debug2("client_check_window_change: changed"); if (compat20) { channel_send_window_changes(); } else { if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) return; packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); packet_put_int((u_int)ws.ws_col); packet_put_int((u_int)ws.ws_xpixel); packet_put_int((u_int)ws.ws_ypixel); packet_send(); } } static int client_global_request_reply(int type, u_int32_t seq, void *ctxt) { struct global_confirm *gc; if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) return 0; if (gc->cb != NULL) gc->cb(type, seq, gc->ctx); if (--gc->ref_count <= 0) { TAILQ_REMOVE(&global_confirms, gc, entry); explicit_bzero(gc, sizeof(*gc)); free(gc); } packet_set_alive_timeouts(0); return 0; } static void server_alive_check(void) { if (packet_inc_alive_timeouts() > options.server_alive_count_max) { logit("Timeout, server %s not responding.", host); cleanup_exit(255); } packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("keepalive@openssh.com"); packet_put_char(1); /* boolean: want reply */ packet_send(); /* Insert an empty placeholder to maintain ordering */ client_register_global_confirm(NULL, NULL); } /* * Waits until the client can do something (some data becomes available on * one of the file descriptors). */ static void client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, int rekeying) { struct timeval tv, *tvp; int timeout_secs; time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); int ret; /* Add any selections by the channel mechanism. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, &minwait_secs, rekeying); if (!compat20) { /* Read from the connection, unless our buffers are full. */ if (buffer_len(&stdout_buffer) < buffer_high && buffer_len(&stderr_buffer) < buffer_high && channel_not_very_much_buffered_data()) FD_SET(connection_in, *readsetp); /* * Read from stdin, unless we have seen EOF or have very much * buffered data to send to the server. */ if (!stdin_eof && packet_not_very_much_data_to_write()) FD_SET(fileno(stdin), *readsetp); /* Select stdout/stderr if have data in buffer. */ if (buffer_len(&stdout_buffer) > 0) FD_SET(fileno(stdout), *writesetp); if (buffer_len(&stderr_buffer) > 0) FD_SET(fileno(stderr), *writesetp); } else { /* channel_prepare_select could have closed the last channel */ if (session_closed && !channel_still_open() && !packet_have_data_to_write()) { /* clear mask since we did not call select() */ memset(*readsetp, 0, *nallocp); memset(*writesetp, 0, *nallocp); return; } else { FD_SET(connection_in, *readsetp); } } /* Select server connection if have data to write to the server. */ if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); /* * Wait for something to happen. This will suspend the process until * some selected descriptor can be read, written, or has some other * event pending, or a timeout expires. */ timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ if (options.server_alive_interval > 0 && compat20) { timeout_secs = options.server_alive_interval; server_alive_time = now + options.server_alive_interval; } if (options.rekey_interval > 0 && compat20 && !rekeying) timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout()); set_control_persist_exit_time(); if (control_persist_exit_time > 0) { timeout_secs = MIN(timeout_secs, control_persist_exit_time - now); if (timeout_secs < 0) timeout_secs = 0; } if (minwait_secs != 0) timeout_secs = MIN(timeout_secs, (int)minwait_secs); if (timeout_secs == INT_MAX) tvp = NULL; else { tv.tv_sec = timeout_secs; tv.tv_usec = 0; tvp = &tv; } ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); if (ret < 0) { char buf[100]; /* * We have to clear the select masks, because we return. * We have to return, because the mainloop checks for the flags * set by the signal handlers. */ memset(*readsetp, 0, *nallocp); memset(*writesetp, 0, *nallocp); if (errno == EINTR) return; /* Note: we might still have data in the buffers. */ snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; } else if (ret == 0) { /* * Timeout. Could have been either keepalive or rekeying. * Keepalive we check here, rekeying is checked in clientloop. */ if (server_alive_time != 0 && server_alive_time <= monotime()) server_alive_check(); } } static void client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) { /* Flush stdout and stderr buffers. */ if (buffer_len(bout) > 0) atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); if (buffer_len(berr) > 0) atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* * Free (and clear) the buffer to reduce the amount of data that gets * written to swap. */ buffer_free(bin); buffer_free(bout); buffer_free(berr); /* Send the suspend signal to the program itself. */ kill(getpid(), SIGTSTP); /* Reset window sizes in case they have changed */ received_window_change_signal = 1; /* OK, we have been continued by the user. Reinitialize buffers. */ buffer_init(bin); buffer_init(bout); buffer_init(berr); enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); } static void client_process_net_input(fd_set *readset) { int len; char buf[SSH_IOBUFSZ]; /* * Read input from the server, and add any such data to the buffer of * the packet subsystem. */ if (FD_ISSET(connection_in, readset)) { /* Read as much as possible. */ len = read(connection_in, buf, sizeof(buf)); if (len == 0) { /* * Received EOF. The remote host has closed the * connection. */ snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", host); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; } /* * There is a kernel bug on Solaris that causes select to * sometimes wake up even though there is no data available. */ if (len < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) len = 0; if (len < 0) { /* * An error has encountered. Perhaps there is a * network problem. */ snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", host, strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; } packet_process_incoming(buf, len); } } static void client_status_confirm(int type, Channel *c, void *ctx) { struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; char errmsg[256]; int tochan; /* * If a TTY was explicitly requested, then a failure to allocate * one is fatal. */ if (cr->action == CONFIRM_TTY && (options.request_tty == REQUEST_TTY_FORCE || options.request_tty == REQUEST_TTY_YES)) cr->action = CONFIRM_CLOSE; /* XXX supress on mux _client_ quietmode */ tochan = options.log_level >= SYSLOG_LEVEL_ERROR && c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; if (type == SSH2_MSG_CHANNEL_SUCCESS) { debug2("%s request accepted on channel %d", cr->request_type, c->self); } else if (type == SSH2_MSG_CHANNEL_FAILURE) { if (tochan) { snprintf(errmsg, sizeof(errmsg), "%s request failed\r\n", cr->request_type); } else { snprintf(errmsg, sizeof(errmsg), "%s request failed on channel %d", cr->request_type, c->self); } /* If error occurred on primary session channel, then exit */ if (cr->action == CONFIRM_CLOSE && c->self == session_ident) fatal("%s", errmsg); /* * If error occurred on mux client, append to * their stderr. */ if (tochan) { buffer_append(&c->extended, errmsg, strlen(errmsg)); } else error("%s", errmsg); if (cr->action == CONFIRM_TTY) { /* * If a TTY allocation error occurred, then arrange * for the correct TTY to leave raw mode. */ if (c->self == session_ident) leave_raw_mode(0); else mux_tty_alloc_failed(c); } else if (cr->action == CONFIRM_CLOSE) { chan_read_failed(c); chan_write_failed(c); } } free(cr); } static void client_abandon_status_confirm(Channel *c, void *ctx) { free(ctx); } void client_expect_confirm(int id, const char *request, enum confirm_action action) { struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr)); cr->request_type = request; cr->action = action; channel_register_status_confirm(id, client_status_confirm, client_abandon_status_confirm, cr); } void client_register_global_confirm(global_confirm_cb *cb, void *ctx) { struct global_confirm *gc, *last_gc; /* Coalesce identical callbacks */ last_gc = TAILQ_LAST(&global_confirms, global_confirms); if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) { if (++last_gc->ref_count >= INT_MAX) fatal("%s: last_gc->ref_count = %d", __func__, last_gc->ref_count); return; } gc = xcalloc(1, sizeof(*gc)); gc->cb = cb; gc->ctx = ctx; gc->ref_count = 1; TAILQ_INSERT_TAIL(&global_confirms, gc, entry); } static void process_cmdline(void) { void (*handler)(int); char *s, *cmd; int ok, delete = 0, local = 0, remote = 0, dynamic = 0; struct Forward fwd; memset(&fwd, 0, sizeof(fwd)); leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); handler = signal(SIGINT, SIG_IGN); cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); if (s == NULL) goto out; while (isspace((u_char)*s)) s++; if (*s == '-') s++; /* Skip cmdline '-', if any */ if (*s == '\0') goto out; if (*s == 'h' || *s == 'H' || *s == '?') { logit("Commands:"); logit(" -L[bind_address:]port:host:hostport " "Request local forward"); logit(" -R[bind_address:]port:host:hostport " "Request remote forward"); logit(" -D[bind_address:]port " "Request dynamic forward"); logit(" -KL[bind_address:]port " "Cancel local forward"); logit(" -KR[bind_address:]port " "Cancel remote forward"); logit(" -KD[bind_address:]port " "Cancel dynamic forward"); if (!options.permit_local_command) goto out; logit(" !args " "Execute local command"); goto out; } if (*s == '!' && options.permit_local_command) { s++; ssh_local_cmd(s); goto out; } if (*s == 'K') { delete = 1; s++; } if (*s == 'L') local = 1; else if (*s == 'R') remote = 1; else if (*s == 'D') dynamic = 1; else { logit("Invalid command."); goto out; } if (delete && !compat20) { logit("Not supported for SSH protocol version 1."); goto out; } while (isspace((u_char)*++s)) ; /* XXX update list of forwards in options */ if (delete) { /* We pass 1 for dynamicfwd to restrict to 1 or 2 fields. */ if (!parse_forward(&fwd, s, 1, 0)) { logit("Bad forwarding close specification."); goto out; } if (remote) ok = channel_request_rforward_cancel(&fwd) == 0; else if (dynamic) ok = channel_cancel_lport_listener(&fwd, 0, &options.fwd_opts) > 0; else ok = channel_cancel_lport_listener(&fwd, CHANNEL_CANCEL_PORT_STATIC, &options.fwd_opts) > 0; if (!ok) { logit("Unkown port forwarding."); goto out; } logit("Canceled forwarding."); } else { if (!parse_forward(&fwd, s, dynamic, remote)) { logit("Bad forwarding specification."); goto out; } if (local || dynamic) { if (!channel_setup_local_fwd_listener(&fwd, &options.fwd_opts)) { logit("Port forwarding failed."); goto out; } } else { if (channel_request_remote_forwarding(&fwd) < 0) { logit("Port forwarding failed."); goto out; } } logit("Forwarding port."); } out: signal(SIGINT, handler); enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); free(cmd); free(fwd.listen_host); free(fwd.listen_path); free(fwd.connect_host); free(fwd.connect_path); } /* reasons to suppress output of an escape command in help output */ #define SUPPRESS_NEVER 0 /* never suppress, always show */ #define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */ #define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */ #define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */ #define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */ struct escape_help_text { const char *cmd; const char *text; unsigned int flags; }; static struct escape_help_text esc_txt[] = { {".", "terminate session", SUPPRESS_MUXMASTER}, {".", "terminate connection (and any multiplexed sessions)", SUPPRESS_MUXCLIENT}, {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1}, {"C", "open a command line", SUPPRESS_MUXCLIENT}, {"R", "request rekey", SUPPRESS_PROTO1}, {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT}, {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT}, {"#", "list forwarded connections", SUPPRESS_NEVER}, {"&", "background ssh (when waiting for connections to terminate)", SUPPRESS_MUXCLIENT}, {"?", "this message", SUPPRESS_NEVER}, }; static void print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client, int using_stderr) { unsigned int i, suppress_flags; char string[1024]; snprintf(string, sizeof string, "%c?\r\n" "Supported escape sequences:\r\n", escape_char); buffer_append(b, string, strlen(string)); suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) | (mux_client ? SUPPRESS_MUXCLIENT : 0) | (mux_client ? 0 : SUPPRESS_MUXMASTER) | (using_stderr ? 0 : SUPPRESS_SYSLOG); for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) { if (esc_txt[i].flags & suppress_flags) continue; snprintf(string, sizeof string, " %c%-3s - %s\r\n", escape_char, esc_txt[i].cmd, esc_txt[i].text); buffer_append(b, string, strlen(string)); } snprintf(string, sizeof string, " %c%c - send the escape character by typing it twice\r\n" "(Note that escapes are only recognized immediately after " "newline.)\r\n", escape_char, escape_char); buffer_append(b, string, strlen(string)); } /* * Process the characters one by one, call with c==NULL for proto1 case. */ static int process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) { char string[1024]; pid_t pid; int bytes = 0; u_int i; u_char ch; char *s; int *escape_pendingp, escape_char; struct escape_filter_ctx *efc; if (c == NULL) { escape_pendingp = &escape_pending1; escape_char = escape_char1; } else { if (c->filter_ctx == NULL) return 0; efc = (struct escape_filter_ctx *)c->filter_ctx; escape_pendingp = &efc->escape_pending; escape_char = efc->escape_char; } if (len <= 0) return (0); for (i = 0; i < (u_int)len; i++) { /* Get one character at a time. */ ch = buf[i]; if (*escape_pendingp) { /* We have previously seen an escape character. */ /* Clear the flag now. */ *escape_pendingp = 0; /* Process the escaped character. */ switch (ch) { case '.': /* Terminate the connection. */ snprintf(string, sizeof string, "%c.\r\n", escape_char); buffer_append(berr, string, strlen(string)); if (c && c->ctl_chan != -1) { chan_read_failed(c); chan_write_failed(c); if (c->detach_user) c->detach_user(c->self, NULL); c->type = SSH_CHANNEL_ABANDONED; buffer_clear(&c->input); chan_ibuf_empty(c); return 0; } else quit_pending = 1; return -1; case 'Z' - 64: /* XXX support this for mux clients */ if (c && c->ctl_chan != -1) { char b[16]; noescape: if (ch == 'Z' - 64) snprintf(b, sizeof b, "^Z"); else snprintf(b, sizeof b, "%c", ch); snprintf(string, sizeof string, "%c%s escape not available to " "multiplexed sessions\r\n", escape_char, b); buffer_append(berr, string, strlen(string)); continue; } /* Suspend the program. Inform the user */ snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); buffer_append(berr, string, strlen(string)); /* Restore terminal modes and suspend. */ client_suspend_self(bin, bout, berr); /* We have been continued. */ continue; case 'B': if (compat20) { snprintf(string, sizeof string, "%cB\r\n", escape_char); buffer_append(berr, string, strlen(string)); channel_request_start(c->self, "break", 0); packet_put_int(1000); packet_send(); } continue; case 'R': if (compat20) { if (datafellows & SSH_BUG_NOREKEY) logit("Server does not " "support re-keying"); else need_rekeying = 1; } continue; case 'V': /* FALLTHROUGH */ case 'v': if (c && c->ctl_chan != -1) goto noescape; if (!log_is_on_stderr()) { snprintf(string, sizeof string, "%c%c [Logging to syslog]\r\n", escape_char, ch); buffer_append(berr, string, strlen(string)); continue; } if (ch == 'V' && options.log_level > SYSLOG_LEVEL_QUIET) log_change_level(--options.log_level); if (ch == 'v' && options.log_level < SYSLOG_LEVEL_DEBUG3) log_change_level(++options.log_level); snprintf(string, sizeof string, "%c%c [LogLevel %s]\r\n", escape_char, ch, log_level_name(options.log_level)); buffer_append(berr, string, strlen(string)); continue; case '&': if (c && c->ctl_chan != -1) goto noescape; /* * Detach the program (continue to serve * connections, but put in background and no * more new connections). */ /* Restore tty modes. */ leave_raw_mode( options.request_tty == REQUEST_TTY_FORCE); /* Stop listening for new connections. */ channel_stop_listening(); snprintf(string, sizeof string, "%c& [backgrounded]\n", escape_char); buffer_append(berr, string, strlen(string)); /* Fork into background. */ pid = fork(); if (pid < 0) { error("fork: %.100s", strerror(errno)); continue; } if (pid != 0) { /* This is the parent. */ /* The parent just exits. */ exit(0); } /* The child continues serving connections. */ if (compat20) { buffer_append(bin, "\004", 1); /* fake EOF on stdin */ return -1; } else if (!stdin_eof) { /* * Sending SSH_CMSG_EOF alone does not * always appear to be enough. So we * try to send an EOF character first. */ packet_start(SSH_CMSG_STDIN_DATA); packet_put_string("\004", 1); packet_send(); /* Close stdin. */ stdin_eof = 1; if (buffer_len(bin) == 0) { packet_start(SSH_CMSG_EOF); packet_send(); } } continue; case '?': print_escape_help(berr, escape_char, compat20, (c && c->ctl_chan != -1), log_is_on_stderr()); continue; case '#': snprintf(string, sizeof string, "%c#\r\n", escape_char); buffer_append(berr, string, strlen(string)); s = channel_open_message(); buffer_append(berr, s, strlen(s)); free(s); continue; case 'C': if (c && c->ctl_chan != -1) goto noescape; process_cmdline(); continue; default: if (ch != escape_char) { buffer_put_char(bin, escape_char); bytes++; } /* Escaped characters fall through here */ break; } } else { /* * The previous character was not an escape char. * Check if this is an escape. */ if (last_was_cr && ch == escape_char) { /* * It is. Set the flag and continue to * next character. */ *escape_pendingp = 1; continue; } } /* * Normal character. Record whether it was a newline, * and append it to the buffer. */ last_was_cr = (ch == '\r' || ch == '\n'); buffer_put_char(bin, ch); bytes++; } return bytes; } static void client_process_input(fd_set *readset) { int len; char buf[SSH_IOBUFSZ]; /* Read input from stdin. */ if (FD_ISSET(fileno(stdin), readset)) { /* Read as much as possible. */ len = read(fileno(stdin), buf, sizeof(buf)); if (len < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) return; /* we'll try again later */ if (len <= 0) { /* * Received EOF or error. They are treated * similarly, except that an error message is printed * if it was an error condition. */ if (len < 0) { snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); } /* Mark that we have seen EOF. */ stdin_eof = 1; /* * Send an EOF message to the server unless there is * data in the buffer. If there is data in the * buffer, no message will be sent now. Code * elsewhere will send the EOF when the buffer * becomes empty if stdin_eof is set. */ if (buffer_len(&stdin_buffer) == 0) { packet_start(SSH_CMSG_EOF); packet_send(); } } else if (escape_char1 == SSH_ESCAPECHAR_NONE) { /* * Normal successful read, and no escape character. * Just append the data to buffer. */ buffer_append(&stdin_buffer, buf, len); } else { /* * Normal, successful read. But we have an escape * character and have to process the characters one * by one. */ if (process_escapes(NULL, &stdin_buffer, &stdout_buffer, &stderr_buffer, buf, len) == -1) return; } } } static void client_process_output(fd_set *writeset) { int len; char buf[100]; /* Write buffered output to stdout. */ if (FD_ISSET(fileno(stdout), writeset)) { /* Write as much data as possible. */ len = write(fileno(stdout), buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); if (len <= 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) len = 0; else { /* * An error or EOF was encountered. Put an * error message to stderr buffer. */ snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; } } /* Consume printed data from the buffer. */ buffer_consume(&stdout_buffer, len); } /* Write buffered output to stderr. */ if (FD_ISSET(fileno(stderr), writeset)) { /* Write as much data as possible. */ len = write(fileno(stderr), buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); if (len <= 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) len = 0; else { /* * EOF or error, but can't even print * error message. */ quit_pending = 1; return; } } /* Consume printed characters from the buffer. */ buffer_consume(&stderr_buffer, len); } } /* * Get packets from the connection input buffer, and process them as long as * there are packets available. * * Any unknown packets received during the actual * session cause the session to terminate. This is * intended to make debugging easier since no * confirmations are sent. Any compatible protocol * extensions must be negotiated during the * preparatory phase. */ static void client_process_buffered_input_packets(void) { dispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state); } /* scan buf[] for '~' before sending data to the peer */ /* Helper: allocate a new escape_filter_ctx and fill in its escape char */ void * client_new_escape_filter_ctx(int escape_char) { struct escape_filter_ctx *ret; ret = xcalloc(1, sizeof(*ret)); ret->escape_pending = 0; ret->escape_char = escape_char; return (void *)ret; } /* Free the escape filter context on channel free */ void client_filter_cleanup(int cid, void *ctx) { free(ctx); } int client_simple_escape_filter(Channel *c, char *buf, int len) { if (c->extended_usage != CHAN_EXTENDED_WRITE) return 0; return process_escapes(c, &c->input, &c->output, &c->extended, buf, len); } static void client_channel_closed(int id, void *arg) { channel_cancel_cleanup(id); session_closed = 1; leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); } /* * Implements the interactive session with the server. This is called after * the user has been authenticated, and a command has been started on the * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character * used as an escape character for terminating or suspending the session. */ int client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; int r, max_fd = 0, max_fd2 = 0, len; u_int64_t ibytes, obytes; u_int nalloc = 0; char buf[100]; debug("Entering interactive session."); if (options.control_master && ! option_clear_or_none(options.control_path)) { debug("pledge: id"); if (pledge("stdio rpath wpath cpath unix inet dns proc exec id tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); } else if (options.forward_x11 || options.permit_local_command) { debug("pledge: exec"); if (pledge("stdio rpath wpath cpath unix inet dns proc exec tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); } else if (options.update_hostkeys) { debug("pledge: filesystem full"); if (pledge("stdio rpath wpath cpath unix inet dns proc tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); } else if (! option_clear_or_none(options.proxy_command)) { debug("pledge: proc"); if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); } else { debug("pledge: network"); if (pledge("stdio unix inet dns tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); } start_time = get_current_time(); /* Initialize variables. */ escape_pending1 = 0; last_was_cr = 1; exit_status = -1; stdin_eof = 0; buffer_high = 64 * 1024; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); max_fd = MAX(connection_in, connection_out); if (!compat20) { /* enable nonblocking unless tty */ if (!isatty(fileno(stdin))) set_nonblock(fileno(stdin)); if (!isatty(fileno(stdout))) set_nonblock(fileno(stdout)); if (!isatty(fileno(stderr))) set_nonblock(fileno(stderr)); max_fd = MAX(max_fd, fileno(stdin)); max_fd = MAX(max_fd, fileno(stdout)); max_fd = MAX(max_fd, fileno(stderr)); } quit_pending = 0; escape_char1 = escape_char_arg; /* Initialize buffers. */ buffer_init(&stdin_buffer); buffer_init(&stdout_buffer); buffer_init(&stderr_buffer); client_init_dispatch(); /* * Set signal handlers, (e.g. to restore non-blocking mode) * but don't overwrite SIG_IGN, matches behaviour from rsh(1) */ if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, signal_handler); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, signal_handler); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, signal_handler); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, signal_handler); signal(SIGWINCH, window_change_handler); if (have_pty) enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); if (compat20) { session_ident = ssh2_chan_id; if (session_ident != -1) { if (escape_char_arg != SSH_ESCAPECHAR_NONE) { channel_register_filter(session_ident, client_simple_escape_filter, NULL, client_filter_cleanup, client_new_escape_filter_ctx( escape_char_arg)); } channel_register_cleanup(session_ident, client_channel_closed, 0); } } else { /* Check if we should immediately send eof on stdin. */ client_check_initial_eof_on_stdin(); } /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { /* Process buffered packets sent by the server. */ client_process_buffered_input_packets(); if (compat20 && session_closed && !channel_still_open()) break; if (ssh_packet_is_rekeying(active_state)) { debug("rekeying in progress"); } else if (need_rekeying) { /* manual rekey request */ debug("need rekeying"); if ((r = kex_start_rekex(active_state)) != 0) fatal("%s: kex_start_rekex: %s", __func__, ssh_err(r)); need_rekeying = 0; } else { /* * Make packets of buffered stdin data, and buffer * them for sending to the server. */ if (!compat20) client_make_packets_from_stdin_data(); /* * Make packets from buffered channel data, and * enqueue them for sending to the server. */ if (packet_not_very_much_data_to_write()) channel_output_poll(); /* * Check if the window size has changed, and buffer a * message about it to the server if so. */ client_check_window_change(); if (quit_pending) break; } /* * Wait until we have something to do (something becomes * available on one of the descriptors). */ max_fd2 = max_fd; client_wait_until_can_do_something(&readset, &writeset, &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); if (quit_pending) break; /* Do channel operations unless rekeying in progress. */ if (!ssh_packet_is_rekeying(active_state)) channel_after_select(readset, writeset); /* Buffer input from the connection. */ client_process_net_input(readset); if (quit_pending) break; if (!compat20) { /* Buffer data from stdin */ client_process_input(readset); /* * Process output to stdout and stderr. Output to * the connection is processed elsewhere (above). */ client_process_output(writeset); } /* * Send as much buffered packet data as possible to the * sender. */ if (FD_ISSET(connection_out, writeset)) packet_write_poll(); /* * If we are a backgrounded control master, and the * timeout has expired without any active client * connections, then quit. */ if (control_persist_exit_time > 0) { if (monotime() >= control_persist_exit_time) { debug("ControlPersist timeout expired"); break; } } } free(readset); free(writeset); /* Terminate the session. */ /* Stop watching for window change. */ signal(SIGWINCH, SIG_DFL); if (compat20) { packet_start(SSH2_MSG_DISCONNECT); packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); packet_put_cstring("disconnected by user"); packet_put_cstring(""); /* language tag */ packet_send(); packet_write_wait(); } channel_free_all(); if (have_pty) leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* restore blocking io */ if (!isatty(fileno(stdin))) unset_nonblock(fileno(stdin)); if (!isatty(fileno(stdout))) unset_nonblock(fileno(stdout)); if (!isatty(fileno(stderr))) unset_nonblock(fileno(stderr)); /* * If there was no shell or command requested, there will be no remote * exit status to be returned. In that case, clear error code if the * connection was deliberately terminated at this end. */ if (no_shell_flag && received_signal == SIGTERM) { received_signal = 0; exit_status = 0; } if (received_signal) fatal("Killed by signal %d.", (int) received_signal); /* * In interactive mode (with pseudo tty) display a message indicating * that the connection has been closed. */ if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); buffer_append(&stderr_buffer, buf, strlen(buf)); } /* Output any buffered data for stdout. */ if (buffer_len(&stdout_buffer) > 0) { len = atomicio(vwrite, fileno(stdout), buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); if (len < 0 || (u_int)len != buffer_len(&stdout_buffer)) error("Write failed flushing stdout buffer."); else buffer_consume(&stdout_buffer, len); } /* Output any buffered data for stderr. */ if (buffer_len(&stderr_buffer) > 0) { len = atomicio(vwrite, fileno(stderr), buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); if (len < 0 || (u_int)len != buffer_len(&stderr_buffer)) error("Write failed flushing stderr buffer."); else buffer_consume(&stderr_buffer, len); } /* Clear and free any buffers. */ explicit_bzero(buf, sizeof(buf)); buffer_free(&stdin_buffer); buffer_free(&stdout_buffer); buffer_free(&stderr_buffer); /* Report bytes transferred, and transfer rates. */ total_time = get_current_time() - start_time; packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", (unsigned long long)obytes, (unsigned long long)ibytes, total_time); if (total_time > 0) verbose("Bytes per second: sent %.1f, received %.1f", obytes / total_time, ibytes / total_time); /* Return the exit status of the program. */ debug("Exit status %d", exit_status); return exit_status; } /*********/ static int client_input_stdout_data(int type, u_int32_t seq, void *ctxt) { u_int data_len; char *data = packet_get_string(&data_len); packet_check_eom(); buffer_append(&stdout_buffer, data, data_len); explicit_bzero(data, data_len); free(data); return 0; } static int client_input_stderr_data(int type, u_int32_t seq, void *ctxt) { u_int data_len; char *data = packet_get_string(&data_len); packet_check_eom(); buffer_append(&stderr_buffer, data, data_len); explicit_bzero(data, data_len); free(data); return 0; } static int client_input_exit_status(int type, u_int32_t seq, void *ctxt) { exit_status = packet_get_int(); packet_check_eom(); /* Acknowledge the exit. */ packet_start(SSH_CMSG_EXIT_CONFIRMATION); packet_send(); /* * Must wait for packet to be sent since we are * exiting the loop. */ packet_write_wait(); /* Flag that we want to exit. */ quit_pending = 1; return 0; } static int client_input_agent_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; int r, remote_id, sock; /* Read the remote channel number from the message. */ remote_id = packet_get_int(); packet_check_eom(); /* * Get a connection to the local authentication agent (this may again * get forwarded). */ if ((r = ssh_get_authentication_socket(&sock)) != 0 && r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); /* * If we could not connect the agent, send an error message back to * the server. This should never happen unless the agent dies, * because authentication forwarding is only enabled if we have an * agent. */ if (sock >= 0) { c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, -1, 0, 0, 0, "authentication agent connection", 1); c->remote_id = remote_id; c->force_drain = 1; } if (c == NULL) { packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); } else { /* Send a confirmation to the remote host. */ debug("Forwarding authentication connection."); packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(remote_id); packet_put_int(c->self); } packet_send(); return 0; } static Channel * client_request_forwarded_tcpip(const char *request_type, int rchan) { Channel *c = NULL; char *listen_address, *originator_address; u_short listen_port, originator_port; /* Get rest of the packet */ listen_address = packet_get_string(NULL); listen_port = packet_get_int(); originator_address = packet_get_string(NULL); originator_port = packet_get_int(); packet_check_eom(); debug("%s: listen %s port %d, originator %s port %d", __func__, listen_address, listen_port, originator_address, originator_port); c = channel_connect_by_listen_address(listen_address, listen_port, "forwarded-tcpip", originator_address); free(originator_address); free(listen_address); return c; } static Channel * client_request_forwarded_streamlocal(const char *request_type, int rchan) { Channel *c = NULL; char *listen_path; /* Get the remote path. */ listen_path = packet_get_string(NULL); /* XXX: Skip reserved field for now. */ if (packet_get_string_ptr(NULL) == NULL) fatal("%s: packet_get_string_ptr failed", __func__); packet_check_eom(); debug("%s: %s", __func__, listen_path); c = channel_connect_by_listen_path(listen_path, "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); free(listen_path); return c; } static Channel * client_request_x11(const char *request_type, int rchan) { Channel *c = NULL; char *originator; u_short originator_port; int sock; if (!options.forward_x11) { error("Warning: ssh server tried X11 forwarding."); error("Warning: this is probably a break-in attempt by a " "malicious server."); return NULL; } if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { verbose("Rejected X11 connection after ForwardX11Timeout " "expired"); return NULL; } originator = packet_get_string(NULL); if (datafellows & SSH_BUG_X11FWD) { debug2("buggy server: x11 request w/o originator_port"); originator_port = 0; } else { originator_port = packet_get_int(); } packet_check_eom(); /* XXX check permission */ debug("client_request_x11: request from %s %d", originator, originator_port); free(originator); sock = x11_connect_display(); if (sock < 0) return NULL; c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); c->force_drain = 1; return c; } static Channel * client_request_agent(const char *request_type, int rchan) { Channel *c = NULL; int r, sock; if (!options.forward_agent) { error("Warning: ssh server tried agent forwarding."); error("Warning: this is probably a break-in attempt by a " "malicious server."); return NULL; } if ((r = ssh_get_authentication_socket(&sock)) != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); return NULL; } c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "authentication agent connection", 1); c->force_drain = 1; return c; } int client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) { Channel *c; int fd; if (tun_mode == SSH_TUNMODE_NO) return 0; if (!compat20) { error("Tunnel forwarding is not supported for protocol 1"); return -1; } debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); /* Open local tunnel device */ if ((fd = tun_open(local_tun, tun_mode)) == -1) { error("Tunnel device open failed."); return -1; } c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; #if defined(SSH_TUN_FILTER) if (options.tun_open == SSH_TUNMODE_POINTOPOINT) channel_register_filter(c->self, sys_tun_infilter, sys_tun_outfilter, NULL, NULL); #endif packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring("tun@openssh.com"); packet_put_int(c->self); packet_put_int(c->local_window_max); packet_put_int(c->local_maxpacket); packet_put_int(tun_mode); packet_put_int(remote_tun); packet_send(); return 0; } /* XXXX move to generic input handler */ static int client_input_channel_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; char *ctype; int rchan; u_int rmaxpack, rwindow, len; ctype = packet_get_string(&len); rchan = packet_get_int(); rwindow = packet_get_int(); rmaxpack = packet_get_int(); debug("client_input_channel_open: ctype %s rchan %d win %d max %d", ctype, rchan, rwindow, rmaxpack); if (strcmp(ctype, "forwarded-tcpip") == 0) { c = client_request_forwarded_tcpip(ctype, rchan); } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { c = client_request_forwarded_streamlocal(ctype, rchan); } else if (strcmp(ctype, "x11") == 0) { c = client_request_x11(ctype, rchan); } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { c = client_request_agent(ctype, rchan); } /* XXX duplicate : */ if (c != NULL) { debug("confirm %s", ctype); c->remote_id = rchan; c->remote_window = rwindow; c->remote_maxpacket = rmaxpack; if (c->type != SSH_CHANNEL_CONNECTING) { packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(c->remote_id); packet_put_int(c->self); packet_put_int(c->local_window); packet_put_int(c->local_maxpacket); packet_send(); } } else { debug("failure %s", ctype); packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); if (!(datafellows & SSH_BUG_OPENFAILURE)) { packet_put_cstring("open failed"); packet_put_cstring(""); } packet_send(); } free(ctype); return 0; } static int client_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; int exitval, id, reply, success = 0; char *rtype; id = packet_get_int(); rtype = packet_get_string(NULL); reply = packet_get_char(); debug("client_input_channel_req: channel %d rtype %s reply %d", id, rtype, reply); if (id == -1) { error("client_input_channel_req: request for channel -1"); } else if ((c = channel_lookup(id)) == NULL) { error("client_input_channel_req: channel %d: " "unknown channel", id); } else if (strcmp(rtype, "eow@openssh.com") == 0) { packet_check_eom(); chan_rcvd_eow(c); } else if (strcmp(rtype, "exit-status") == 0) { exitval = packet_get_int(); if (c->ctl_chan != -1) { mux_exit_message(c, exitval); success = 1; } else if (id == session_ident) { /* Record exit value of local session */ success = 1; exit_status = exitval; } else { /* Probably for a mux channel that has already closed */ debug("%s: no sink for exit-status on channel %d", __func__, id); } packet_check_eom(); } if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); packet_put_int(c->remote_id); packet_send(); } free(rtype); return 0; } struct hostkeys_update_ctx { /* The hostname and (optionally) IP address string for the server */ char *host_str, *ip_str; /* * Keys received from the server and a flag for each indicating * whether they already exist in known_hosts. * keys_seen is filled in by hostkeys_find() and later (for new * keys) by client_global_hostkeys_private_confirm(). */ struct sshkey **keys; int *keys_seen; size_t nkeys; size_t nnew; /* * Keys that are in known_hosts, but were not present in the update * from the server (i.e. scheduled to be deleted). * Filled in by hostkeys_find(). */ struct sshkey **old_keys; size_t nold; }; static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx) { size_t i; if (ctx == NULL) return; for (i = 0; i < ctx->nkeys; i++) sshkey_free(ctx->keys[i]); free(ctx->keys); free(ctx->keys_seen); for (i = 0; i < ctx->nold; i++) sshkey_free(ctx->old_keys[i]); free(ctx->old_keys); free(ctx->host_str); free(ctx->ip_str); free(ctx); } static int hostkeys_find(struct hostkey_foreach_line *l, void *_ctx) { struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; size_t i; struct sshkey **tmp; if (l->status != HKF_STATUS_MATCHED || l->key == NULL || l->key->type == KEY_RSA1) return 0; /* Mark off keys we've already seen for this host */ for (i = 0; i < ctx->nkeys; i++) { if (sshkey_equal(l->key, ctx->keys[i])) { debug3("%s: found %s key at %s:%ld", __func__, sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum); ctx->keys_seen[i] = 1; return 0; } } /* This line contained a key that not offered by the server */ debug3("%s: deprecated %s key at %s:%ld", __func__, sshkey_ssh_name(l->key), l->path, l->linenum); if ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1, sizeof(*ctx->old_keys))) == NULL) fatal("%s: reallocarray failed nold = %zu", __func__, ctx->nold); ctx->old_keys = tmp; ctx->old_keys[ctx->nold++] = l->key; l->key = NULL; return 0; } static void update_known_hosts(struct hostkeys_update_ctx *ctx) { int r, was_raw = 0; int loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE; char *fp, *response; size_t i; for (i = 0; i < ctx->nkeys; i++) { if (ctx->keys_seen[i] != 2) continue; if ((fp = sshkey_fingerprint(ctx->keys[i], options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Learned new hostkey: %s %s", sshkey_type(ctx->keys[i]), fp); free(fp); } for (i = 0; i < ctx->nold; i++) { if ((fp = sshkey_fingerprint(ctx->old_keys[i], options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", sshkey_type(ctx->old_keys[i]), fp); free(fp); } if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { if (get_saved_tio() != NULL) { leave_raw_mode(1); was_raw = 1; } response = NULL; for (i = 0; !quit_pending && i < 3; i++) { free(response); response = read_passphrase("Accept updated hostkeys? " "(yes/no): ", RP_ECHO); if (strcasecmp(response, "yes") == 0) break; else if (quit_pending || response == NULL || strcasecmp(response, "no") == 0) { options.update_hostkeys = 0; break; } else { do_log2(loglevel, "Please enter " "\"yes\" or \"no\""); } } if (quit_pending || i >= 3 || response == NULL) options.update_hostkeys = 0; free(response); if (was_raw) enter_raw_mode(1); } /* * Now that all the keys are verified, we can go ahead and replace * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't * cancel the operation). */ if (options.update_hostkeys != 0 && (r = hostfile_replace_entries(options.user_hostfiles[0], ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, options.hash_known_hosts, 0, options.fingerprint_hash)) != 0) error("%s: hostfile_replace_entries failed: %s", __func__, ssh_err(r)); } static void client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) { struct ssh *ssh = active_state; /* XXX */ struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; size_t i, ndone; struct sshbuf *signdata; int r; const u_char *sig; size_t siglen; if (ctx->nnew == 0) fatal("%s: ctx->nnew == 0", __func__); /* sanity */ if (type != SSH2_MSG_REQUEST_SUCCESS) { error("Server failed to confirm ownership of " "private host keys"); hostkeys_update_ctx_free(ctx); return; } if ((signdata = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Don't want to accidentally accept an unbound signature */ if (ssh->kex->session_id_len == 0) fatal("%s: ssh->kex->session_id_len == 0", __func__); /* * Expect a signature for each of the ctx->nnew private keys we * haven't seen before. They will be in the same order as the * ctx->keys where the corresponding ctx->keys_seen[i] == 0. */ for (ndone = i = 0; i < ctx->nkeys; i++) { if (ctx->keys_seen[i]) continue; /* Prepare data to be signed: session ID, unique string, key */ sshbuf_reset(signdata); if ( (r = sshbuf_put_cstring(signdata, "hostkeys-prove-00@openssh.com")) != 0 || (r = sshbuf_put_string(signdata, ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || (r = sshkey_puts(ctx->keys[i], signdata)) != 0) fatal("%s: failed to prepare signature: %s", __func__, ssh_err(r)); /* Extract and verify signature */ if ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) { error("%s: couldn't parse message: %s", __func__, ssh_err(r)); goto out; } if ((r = sshkey_verify(ctx->keys[i], sig, siglen, sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) { error("%s: server gave bad signature for %s key %zu", __func__, sshkey_type(ctx->keys[i]), i); goto out; } /* Key is good. Mark it as 'seen' */ ctx->keys_seen[i] = 2; ndone++; } if (ndone != ctx->nnew) fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, ndone, ctx->nnew); /* Shouldn't happen */ ssh_packet_check_eom(ssh); /* Make the edits to known_hosts */ update_known_hosts(ctx); out: hostkeys_update_ctx_free(ctx); } /* * Handle hostkeys-00@openssh.com global request to inform the client of all * the server's hostkeys. The keys are checked against the user's * HostkeyAlgorithms preference before they are accepted. */ static int client_input_hostkeys(void) { struct ssh *ssh = active_state; /* XXX */ const u_char *blob = NULL; size_t i, len = 0; struct sshbuf *buf = NULL; struct sshkey *key = NULL, **tmp; int r; char *fp; static int hostkeys_seen = 0; /* XXX use struct ssh */ extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */ struct hostkeys_update_ctx *ctx = NULL; if (hostkeys_seen) fatal("%s: server already sent hostkeys", __func__); if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK && options.batch_mode) return 1; /* won't ask in batchmode, so don't even try */ if (!options.update_hostkeys || options.num_user_hostfiles <= 0) return 1; ctx = xcalloc(1, sizeof(*ctx)); while (ssh_packet_remaining(ssh) > 0) { sshkey_free(key); key = NULL; if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) { error("%s: couldn't parse message: %s", __func__, ssh_err(r)); goto out; } if ((r = sshkey_from_blob(blob, len, &key)) != 0) { error("%s: parse key: %s", __func__, ssh_err(r)); goto out; } fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); debug3("%s: received %s key %s", __func__, sshkey_type(key), fp); free(fp); /* Check that the key is accepted in HostkeyAlgorithms */ if (match_pattern_list(sshkey_ssh_name(key), options.hostkeyalgorithms ? options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG, 0) != 1) { debug3("%s: %s key not permitted by HostkeyAlgorithms", __func__, sshkey_ssh_name(key)); continue; } /* Skip certs */ if (sshkey_is_cert(key)) { debug3("%s: %s key is a certificate; skipping", __func__, sshkey_ssh_name(key)); continue; } /* Ensure keys are unique */ for (i = 0; i < ctx->nkeys; i++) { if (sshkey_equal(key, ctx->keys[i])) { error("%s: received duplicated %s host key", __func__, sshkey_ssh_name(key)); goto out; } } /* Key is good, record it */ if ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1, sizeof(*ctx->keys))) == NULL) fatal("%s: reallocarray failed nkeys = %zu", __func__, ctx->nkeys); ctx->keys = tmp; ctx->keys[ctx->nkeys++] = key; key = NULL; } if (ctx->nkeys == 0) { debug("%s: server sent no hostkeys", __func__); goto out; } if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) fatal("%s: calloc failed", __func__); get_hostfile_hostname_ipaddr(host, options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL, options.port, &ctx->host_str, options.check_host_ip ? &ctx->ip_str : NULL); /* Find which keys we already know about. */ if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find, ctx, ctx->host_str, ctx->ip_str, HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) { error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); goto out; } /* Figure out if we have any new keys to add */ ctx->nnew = 0; for (i = 0; i < ctx->nkeys; i++) { if (!ctx->keys_seen[i]) ctx->nnew++; } debug3("%s: %zu keys from server: %zu new, %zu retained. %zu to remove", __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold); if (ctx->nnew == 0 && ctx->nold != 0) { /* We have some keys to remove. Just do it. */ update_known_hosts(ctx); } else if (ctx->nnew != 0) { /* * We have received hitherto-unseen keys from the server. * Ask the server to confirm ownership of the private halves. */ debug3("%s: asking server to prove ownership for %zu keys", __func__, ctx->nnew); if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, "hostkeys-prove-00@openssh.com")) != 0 || (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */ fatal("%s: cannot prepare packet: %s", __func__, ssh_err(r)); if ((buf = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); for (i = 0; i < ctx->nkeys; i++) { if (ctx->keys_seen[i]) continue; sshbuf_reset(buf); if ((r = sshkey_putb(ctx->keys[i], buf)) != 0) fatal("%s: sshkey_putb: %s", __func__, ssh_err(r)); if ((r = sshpkt_put_stringb(ssh, buf)) != 0) fatal("%s: sshpkt_put_string: %s", __func__, ssh_err(r)); } if ((r = sshpkt_send(ssh)) != 0) fatal("%s: sshpkt_send: %s", __func__, ssh_err(r)); client_register_global_confirm( client_global_hostkeys_private_confirm, ctx); ctx = NULL; /* will be freed in callback */ } /* Success */ out: hostkeys_update_ctx_free(ctx); sshkey_free(key); sshbuf_free(buf); /* * NB. Return success for all cases. The server doesn't need to know * what the client does with its hosts file. */ return 1; } static int client_input_global_request(int type, u_int32_t seq, void *ctxt) { char *rtype; int want_reply; int success = 0; rtype = packet_get_cstring(NULL); want_reply = packet_get_char(); debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply); if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) success = client_input_hostkeys(); if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); packet_send(); packet_write_wait(); } free(rtype); return 0; } void client_session2_setup(int id, int want_tty, int want_subsystem, const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) { int len; Channel *c = NULL; debug2("%s: id %d", __func__, id); if ((c = channel_lookup(id)) == NULL) fatal("client_session2_setup: channel %d: unknown channel", id); packet_set_interactive(want_tty, options.ip_qos_interactive, options.ip_qos_bulk); if (want_tty) { struct winsize ws; /* Store window size in the packet. */ if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) memset(&ws, 0, sizeof(ws)); channel_request_start(id, "pty-req", 1); client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); packet_put_cstring(term != NULL ? term : ""); packet_put_int((u_int)ws.ws_col); packet_put_int((u_int)ws.ws_row); packet_put_int((u_int)ws.ws_xpixel); packet_put_int((u_int)ws.ws_ypixel); if (tiop == NULL) tiop = get_saved_tio(); tty_make_modes(-1, tiop); packet_send(); /* XXX wait for reply */ c->client_tty = 1; } /* Transfer any environment variables from client to server */ if (options.num_send_env != 0 && env != NULL) { int i, j, matched; char *name, *val; debug("Sending environment."); for (i = 0; env[i] != NULL; i++) { /* Split */ name = xstrdup(env[i]); if ((val = strchr(name, '=')) == NULL) { free(name); continue; } *val++ = '\0'; matched = 0; for (j = 0; j < options.num_send_env; j++) { if (match_pattern(name, options.send_env[j])) { matched = 1; break; } } if (!matched) { debug3("Ignored env %s", name); free(name); continue; } debug("Sending env %s = %s", name, val); channel_request_start(id, "env", 0); packet_put_cstring(name); packet_put_cstring(val); packet_send(); free(name); } } len = buffer_len(cmd); if (len > 0) { if (len > 900) len = 900; if (want_subsystem) { debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); channel_request_start(id, "subsystem", 1); client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); } else { debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); channel_request_start(id, "exec", 1); client_expect_confirm(id, "exec", CONFIRM_CLOSE); } packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); packet_send(); } else { channel_request_start(id, "shell", 1); client_expect_confirm(id, "shell", CONFIRM_CLOSE); packet_send(); } } static void client_init_dispatch_20(void) { dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); /* rekeying */ dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); /* global request reply messages */ dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); } static void client_init_dispatch_13(void) { dispatch_init(NULL); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? &client_input_agent_open : &deny_input_open); dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? &x11_input_open : &deny_input_open); } static void client_init_dispatch_15(void) { client_init_dispatch_13(); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); } static void client_init_dispatch(void) { if (compat20) client_init_dispatch_20(); else if (compat13) client_init_dispatch_13(); else client_init_dispatch_15(); } void client_stop_mux(void) { if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); /* * If we are in persist mode, or don't have a shell, signal that we * should close when all active channels are closed. */ if (options.control_persist || no_shell_flag) { session_closed = 1; setproctitle("[stopped mux]"); } } /* client specific fatal cleanup */ void cleanup_exit(int i) { leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); leave_non_blocking(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); ssh_kill_proxy_command(); _exit(i); } openssh-7.2p2/clientloop.h010064400017500001750000000067331267006270000140040ustar00djmdjm/* $OpenBSD: clientloop.h,v 1.32 2016/01/13 23:04:47 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 /* Client side main loop for the interactive session. */ int client_loop(int, int, int); int client_x11_get_proto(const char *, const char *, u_int, 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 **); int client_request_tun_fwd(int, int, int); void client_stop_mux(void); /* Escape filter for protocol 2 sessions */ void *client_new_escape_filter_ctx(int); void client_filter_cleanup(int, void *); int client_simple_escape_filter(Channel *, char *, int); /* Global request confirmation callbacks */ typedef void global_confirm_cb(int, u_int32_t seq, void *); void client_register_global_confirm(global_confirm_cb *, void *); /* Channel request confirmation callbacks */ enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; void client_expect_confirm(int, const char *, enum confirm_action); /* Multiplexing protocol version */ #define SSHMUX_VER 4 /* 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_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */ #define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */ #define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */ #define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */ void muxserver_listen(void); void muxclient(const char *); void mux_exit_message(Channel *, int); void mux_tty_alloc_failed(Channel *); openssh-7.2p2/compat.c010064400017500001750000000221671267006270000131110ustar00djmdjm/* $OpenBSD: compat.c,v 1.97 2015/08/19 23:21:42 djm 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 #include #include #include #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) { if (compat20) return; 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 */ u_int 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_4*", 0 }, { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH}, { "OpenSSH_6.5*," "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD}, { "OpenSSH*", SSH_NEW_OPENSSH }, { "*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| SSH_BUG_RFWD_ADDR }, { "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 }, { "Cisco-1.*", SSH_BUG_DHGEX_LARGE| SSH_BUG_HOSTKEYS }, { "*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 }, { "PuTTY_Local:*," /* dev versions < Sep 2014 */ "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */ "PuTTY_Release_0.5*," /* 0.58-0.59 */ "PuTTY_Release_0.60*," "PuTTY_Release_0.61*," "PuTTY_Release_0.62*," "PuTTY_Release_0.63*," "PuTTY_Release_0.64*", SSH_OLD_DHGEX }, { "FuTTY*", SSH_OLD_DHGEX }, /* Putty Fork */ { "Probe-*", SSH_BUG_PROBE }, { "TeraTerm SSH*," "TTSSH/1.5.*," "TTSSH/2.1*," "TTSSH/2.2*," "TTSSH/2.3*," "TTSSH/2.4*," "TTSSH/2.5*," "TTSSH/2.6*," "TTSSH/2.70*," "TTSSH/2.71*," "TTSSH/2.72*", SSH_BUG_HOSTKEYS }, { "WinSCP_release_4*," "WinSCP_release_5.0*," "WinSCP_release_5.1*," "WinSCP_release_5.5*," "WinSCP_release_5.6*," "WinSCP_release_5.7," "WinSCP_release_5.7.1," "WinSCP_release_5.7.2," "WinSCP_release_5.7.3," "WinSCP_release_5.7.4", SSH_OLD_DHGEX }, { NULL, 0 } }; /* process table, return first match */ for (i = 0; check[i].pat; i++) { if (match_pattern_list(version, check[i].pat, 0) == 1) { debug("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); datafellows = check[i].bugs; /* XXX for now */ return check[i].bugs; } } debug("no match: %s", version); return 0; } #define SEP "," int proto_spec(const char *spec) { char *s, *p, *q; int ret = SSH_PROTO_UNKNOWN; if (spec == NULL) return ret; q = s = strdup(spec); if (s == NULL) return ret; for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { switch (atoi(p)) { case 1: #ifdef WITH_SSH1 if (ret == SSH_PROTO_UNKNOWN) ret |= SSH_PROTO_1_PREFERRED; ret |= SSH_PROTO_1; #endif break; case 2: ret |= SSH_PROTO_2; break; default: logit("ignoring bad proto spec: '%s'.", p); break; } } free(s); return ret; } /* * Filters a proposal string, excluding any algorithm matching the 'filter' * pattern list. */ static char * filter_proposal(char *proposal, const char *filter) { Buffer b; char *orig_prop, *fix_prop; char *cp, *tmp; buffer_init(&b); tmp = orig_prop = xstrdup(proposal); while ((cp = strsep(&tmp, ",")) != NULL) { if (match_pattern_list(cp, filter, 0) != 1) { if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); buffer_append(&b, cp, strlen(cp)); } else debug2("Compat: skipping algorithm \"%s\"", cp); } buffer_append(&b, "\0", 1); fix_prop = xstrdup((char *)buffer_ptr(&b)); buffer_free(&b); free(orig_prop); return fix_prop; } char * compat_cipher_proposal(char *cipher_prop) { if (!(datafellows & SSH_BUG_BIGENDIANAES)) return cipher_prop; debug2("%s: original cipher proposal: %s", __func__, cipher_prop); cipher_prop = filter_proposal(cipher_prop, "aes*"); debug2("%s: compat cipher proposal: %s", __func__, cipher_prop); if (*cipher_prop == '\0') fatal("No supported ciphers found"); return cipher_prop; } char * compat_pkalg_proposal(char *pkalg_prop) { if (!(datafellows & SSH_BUG_RSASIGMD5)) return pkalg_prop; debug2("%s: original public key proposal: %s", __func__, pkalg_prop); pkalg_prop = filter_proposal(pkalg_prop, "ssh-rsa"); debug2("%s: compat public key proposal: %s", __func__, pkalg_prop); if (*pkalg_prop == '\0') fatal("No supported PK algorithms found"); return pkalg_prop; } char * compat_kex_proposal(char *p) { if ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) return p; debug2("%s: original KEX proposal: %s", __func__, p); if ((datafellows & SSH_BUG_CURVE25519PAD) != 0) p = filter_proposal(p, "curve25519-sha256@libssh.org"); if ((datafellows & SSH_OLD_DHGEX) != 0) { p = filter_proposal(p, "diffie-hellman-group-exchange-sha256"); p = filter_proposal(p, "diffie-hellman-group-exchange-sha1"); } debug2("%s: compat KEX proposal: %s", __func__, p); if (*p == '\0') fatal("No supported key exchange algorithms found"); return p; } openssh-7.2p2/compat.h010064400017500001750000000056341267006270000131160ustar00djmdjm/* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker 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 #define SSH_BUG_RFWD_ADDR 0x02000000 #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 #define SSH_BUG_DHGEX_LARGE 0x40000000 void enable_compat13(void); void enable_compat20(void); u_int compat_datafellows(const char *); int proto_spec(const char *); char *compat_cipher_proposal(char *); char *compat_pkalg_proposal(char *); char *compat_kex_proposal(char *); extern int compat13; extern int compat20; extern int datafellows; #endif openssh-7.2p2/config.guess010075500017500001750000001300271267006270000137750ustar00djmdjm#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2012-12-23' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-gnu exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: openssh-7.2p2/config.sub010075500017500001750000001056721267006270000134500ustar00djmdjm#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2012-12-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: openssh-7.2p2/configure.ac010064400017500001750000004216751267006270000137570ustar00djmdjm# $Id: configure.ac,v 1.583 2014/08/26 20:32:01 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND 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. AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) AC_REVISION($Revision: 1.583 $) AC_CONFIG_SRCDIR([ssh.c]) AC_LANG([C]) AC_CONFIG_HEADER([config.h]) AC_PROG_CC AC_CANONICAL_HOST AC_C_BIGENDIAN # Checks for programs. AC_PROG_AWK AC_PROG_CPP AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_EGREP AC_CHECK_TOOLS([AR], [ar]) AC_PATH_PROG([CAT], [cat]) AC_PATH_PROG([KILL], [kill]) AC_PATH_PROGS([PERL], [perl5 perl]) AC_PATH_PROG([SED], [sed]) AC_SUBST([PERL]) AC_PATH_PROG([ENT], [ent]) AC_SUBST([ENT]) AC_PATH_PROG([TEST_MINUS_S_SH], [bash]) AC_PATH_PROG([TEST_MINUS_S_SH], [ksh]) AC_PATH_PROG([TEST_MINUS_S_SH], [sh]) AC_PATH_PROG([SH], [sh]) AC_PATH_PROG([GROFF], [groff]) AC_PATH_PROG([NROFF], [nroff]) AC_PATH_PROG([MANDOC], [mandoc]) AC_SUBST([TEST_SHELL], [sh]) dnl select manpage formatter if test "x$MANDOC" != "x" ; then MANFMT="$MANDOC" elif test "x$NROFF" != "x" ; then MANFMT="$NROFF -mandoc" elif test "x$GROFF" != "x" ; then MANFMT="$GROFF -mandoc -Tascii" else AC_MSG_WARN([no manpage formatted found]) MANFMT="false" fi AC_SUBST([MANFMT]) dnl for buildpkg.sh AC_PATH_PROG([PATH_GROUPADD_PROG], [groupadd], [groupadd], [/usr/sbin${PATH_SEPARATOR}/etc]) AC_PATH_PROG([PATH_USERADD_PROG], [useradd], [useradd], [/usr/sbin${PATH_SEPARATOR}/etc]) AC_CHECK_PROG([MAKE_PACKAGE_SUPPORTED], [pkgmk], [yes], [no]) if test -x /sbin/sh; then AC_SUBST([STARTUP_SCRIPT_SHELL], [/sbin/sh]) else AC_SUBST([STARTUP_SCRIPT_SHELL], [/bin/sh]) fi # System features AC_SYS_LARGEFILE if test -z "$AR" ; then AC_MSG_ERROR([*** 'ar' missing, please install or fix your \$PATH ***]) fi # Use LOGIN_PROGRAM from environment if possible if test ! -z "$LOGIN_PROGRAM" ; then AC_DEFINE_UNQUOTED([LOGIN_PROGRAM_FALLBACK], ["$LOGIN_PROGRAM"], [If your header files don't define LOGIN_PROGRAM, then use this (detected) from environment and PATH]) else # Search for login AC_PATH_PROG([LOGIN_PROGRAM_FALLBACK], [login]) if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then AC_DEFINE_UNQUOTED([LOGIN_PROGRAM_FALLBACK], ["$LOGIN_PROGRAM_FALLBACK"]) fi fi AC_PATH_PROG([PATH_PASSWD_PROG], [passwd]) if test ! -z "$PATH_PASSWD_PROG" ; then AC_DEFINE_UNQUOTED([_PATH_PASSWD_PROG], ["$PATH_PASSWD_PROG"], [Full path of your "passwd" program]) fi if test -z "$LD" ; then LD=$CC fi AC_SUBST([LD]) AC_C_INLINE AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include ]) AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [ #include #include #include ]) AC_CHECK_DECL([RLIMIT_NPROC], [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [ #include #include ]) AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ #include #include ]) openssl=yes ssh1=no AC_ARG_WITH([openssl], [ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ], [ if test "x$withval" = "xno" ; then openssl=no ssh1=no fi ] ) AC_MSG_CHECKING([whether OpenSSL will be used for cryptography]) if test "x$openssl" = "xyes" ; then AC_MSG_RESULT([yes]) AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography]) else AC_MSG_RESULT([no]) fi AC_ARG_WITH([ssh1], [ --with-ssh1 Enable support for SSH protocol 1], [ if test "x$withval" = "xyes" ; then if test "x$openssl" = "xno" ; then AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled]) fi ssh1=yes elif test "x$withval" = "xno" ; then ssh1=no else AC_MSG_ERROR([unknown --with-ssh1 argument]) fi ] ) AC_MSG_CHECKING([whether SSH protocol 1 support is enabled]) if test "x$ssh1" = "xyes" ; then AC_MSG_RESULT([yes]) AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support]) else AC_MSG_RESULT([no]) fi use_stack_protector=1 use_toolchain_hardening=1 AC_ARG_WITH([stackprotect], [ --without-stackprotect Don't use compiler's stack protection], [ if test "x$withval" = "xno"; then use_stack_protector=0 fi ]) AC_ARG_WITH([hardening], [ --without-hardening Don't use toolchain hardening flags], [ if test "x$withval" = "xno"; then use_toolchain_hardening=0 fi ]) # We use -Werror for the tests only so that we catch warnings like "this is # on by default" for things like -fPIE. AC_MSG_CHECKING([if $CC supports -Werror]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], [ AC_MSG_RESULT([yes]) WERROR="-Werror"], [ AC_MSG_RESULT([no]) WERROR="" ] ) CFLAGS="$saved_CFLAGS" if test "$GCC" = "yes" || test "$GCC" = "egcs"; then OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments]) OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option]) OSSH_CHECK_CFLAG_COMPILE([-Wall]) OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith]) OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized]) OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare]) OSSH_CHECK_CFLAG_COMPILE([-Wformat-security]) OSSH_CHECK_CFLAG_COMPILE([-Wsizeof-pointer-memaccess]) OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign]) OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result]) OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing]) OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2]) if test "x$use_toolchain_hardening" = "x1"; then OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro]) OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now]) OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack]) # NB. -ftrapv expects certain support functions to be present in # the compiler library (libgcc or similar) to detect integer operations # that can overflow. We must check that the result of enabling it # actually links. The test program compiled/linked includes a number # of integer operations that should exercise this. OSSH_CHECK_CFLAG_LINK([-ftrapv]) fi AC_MSG_CHECKING([gcc version]) GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in 1.*) no_attrib_nonnull=1 ;; 2.8* | 2.9*) no_attrib_nonnull=1 ;; 2.*) no_attrib_nonnull=1 ;; *) ;; esac AC_MSG_RESULT([$GCC_VER]) AC_MSG_CHECKING([if $CC accepts -fno-builtin-memset]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-builtin-memset" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char b[10]; memset(b, 0, sizeof(b)); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" ] ) # -fstack-protector-all doesn't always work for some GCC versions # and/or platforms, so we test if we can. If it's not supported # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then for t in -fstack-protector-strong -fstack-protector-all \ -fstack-protector; do AC_MSG_CHECKING([if $CC supports $t]) saved_CFLAGS="$CFLAGS" saved_LDFLAGS="$LDFLAGS" CFLAGS="$CFLAGS $t -Werror" LDFLAGS="$LDFLAGS $t -Werror" AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ char x[256]; snprintf(x, sizeof(x), "XXX"); ]])], [ AC_MSG_RESULT([yes]) CFLAGS="$saved_CFLAGS $t" LDFLAGS="$saved_LDFLAGS $t" AC_MSG_CHECKING([if $t works]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ char x[256]; snprintf(x, sizeof(x), "XXX"); ]])], [ AC_MSG_RESULT([yes]) break ], [ AC_MSG_RESULT([no]) ], [ AC_MSG_WARN([cross compiling: cannot test]) break ] ) ], [ AC_MSG_RESULT([no]) ] ) CFLAGS="$saved_CFLAGS" LDFLAGS="$saved_LDFLAGS" done fi if test -z "$have_llong_max"; then # retry LLONG_MAX with -std=gnu99, needed on some Linuxes unset ac_cv_have_decl_LLONG_MAX saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -std=gnu99" AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], [CFLAGS="$saved_CFLAGS"], [#include ] ) fi fi AC_MSG_CHECKING([if compiler allows __attribute__ on return types]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ #include __attribute__((__unused__)) static void foo(void){return;}]], [[ exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_DEFINE(NO_ATTRIBUTE_ON_RETURN_TYPE, 1, [compiler does not accept __attribute__ on return types]) ] ) if test "x$no_attrib_nonnull" != "x1" ; then AC_DEFINE([HAVE_ATTRIBUTE__NONNULL__], [1], [Have attribute nonnull]) fi AC_ARG_WITH([rpath], [ --without-rpath Disable auto-added -R linker paths], [ if test "x$withval" = "xno" ; then need_dash_r="" fi if test "x$withval" = "xyes" ; then need_dash_r=1 fi ] ) # Allow user to specify flags AC_ARG_WITH([cflags], [ --with-cflags Specify additional flags to pass to compiler], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then CFLAGS="$CFLAGS $withval" fi ] ) AC_ARG_WITH([cppflags], [ --with-cppflags Specify additional flags to pass to preprocessor] , [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then CPPFLAGS="$CPPFLAGS $withval" fi ] ) AC_ARG_WITH([ldflags], [ --with-ldflags Specify additional flags to pass to linker], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then LDFLAGS="$LDFLAGS $withval" fi ] ) AC_ARG_WITH([libs], [ --with-libs Specify additional libraries to link with], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then LIBS="$LIBS $withval" fi ] ) AC_ARG_WITH([Werror], [ --with-Werror Build main code with -Werror], [ if test -n "$withval" && test "x$withval" != "xno"; then werror_flags="-Werror" if test "x${withval}" != "xyes"; then werror_flags="$withval" fi fi ] ) AC_CHECK_HEADERS([ \ blf.h \ bstring.h \ crypt.h \ crypto/sha2.h \ dirent.h \ endian.h \ elf.h \ features.h \ fcntl.h \ floatingpoint.h \ getopt.h \ glob.h \ ia.h \ iaf.h \ inttypes.h \ limits.h \ locale.h \ login.h \ maillock.h \ ndir.h \ net/if_tun.h \ netdb.h \ netgroup.h \ pam/pam_appl.h \ paths.h \ poll.h \ pty.h \ readpassphrase.h \ rpc/types.h \ security/pam_appl.h \ sha2.h \ shadow.h \ stddef.h \ stdint.h \ string.h \ strings.h \ sys/audit.h \ sys/bitypes.h \ sys/bsdtty.h \ sys/capability.h \ sys/cdefs.h \ sys/dir.h \ sys/mman.h \ sys/ndir.h \ sys/poll.h \ sys/prctl.h \ sys/pstat.h \ sys/select.h \ sys/stat.h \ sys/stream.h \ sys/stropts.h \ sys/strtio.h \ sys/statvfs.h \ sys/sysmacros.h \ sys/time.h \ sys/timers.h \ time.h \ tmpdir.h \ ttyent.h \ ucred.h \ unistd.h \ usersec.h \ util.h \ utime.h \ utmp.h \ utmpx.h \ vis.h \ ]) # lastlog.h requires sys/time.h to be included first on Solaris AC_CHECK_HEADERS([lastlog.h], [], [], [ #ifdef HAVE_SYS_TIME_H # include #endif ]) # sys/ptms.h requires sys/stream.h to be included first on Solaris AC_CHECK_HEADERS([sys/ptms.h], [], [], [ #ifdef HAVE_SYS_STREAM_H # include #endif ]) # login_cap.h requires sys/types.h on NetBSD AC_CHECK_HEADERS([login_cap.h], [], [], [ #include ]) # older BSDs need sys/param.h before sys/mount.h AC_CHECK_HEADERS([sys/mount.h], [], [], [ #include ]) # Android requires sys/socket.h to be included before sys/un.h AC_CHECK_HEADERS([sys/un.h], [], [], [ #include #include ]) # Messages for features tested for in target-specific section SIA_MSG="no" SPC_MSG="no" SP_MSG="no" SPP_MSG="no" # Support for Solaris/Illumos privileges (this test is used by both # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" # Check for some target-specific stuff case "$host" in *-*-aix*) # Some versions of VAC won't allow macro redefinitions at # -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that # particularly with older versions of vac or xlc. # It also throws errors about null macro argments, but these are # not fatal. AC_MSG_CHECKING([if compiler allows macro redefinitions]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ #define testmacro foo #define testmacro bar]], [[ exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`" LD="`echo $LD | sed 's/-qlanglvl\=ansi//g'`" CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`" CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`" ] ) AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) if (test -z "$blibpath"); then blibpath="/usr/lib:/lib" fi saved_LDFLAGS="$LDFLAGS" if test "$GCC" = "yes"; then flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:" else flags="-blibpath: -Wl,-blibpath: -Wl,-rpath," fi for tryflags in $flags ;do if (test -z "$blibflags"); then LDFLAGS="$saved_LDFLAGS $tryflags$blibpath" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [blibflags=$tryflags], []) fi done if (test -z "$blibflags"); then AC_MSG_RESULT([not found]) AC_MSG_ERROR([*** must be able to specify blibpath on AIX - check config.log]) else AC_MSG_RESULT([$blibflags]) fi LDFLAGS="$saved_LDFLAGS" dnl Check for authenticate. Might be in libs.a on older AIXes AC_CHECK_FUNC([authenticate], [AC_DEFINE([WITH_AIXAUTHENTICATE], [1], [Define if you want to enable AIX4's authenticate function])], [AC_CHECK_LIB([s], [authenticate], [ AC_DEFINE([WITH_AIXAUTHENTICATE]) LIBS="$LIBS -ls" ]) ]) dnl Check for various auth function declarations in headers. AC_CHECK_DECLS([authenticate, loginrestrictions, loginsuccess, passwdexpired, setauthdb], , , [#include ]) dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2) AC_CHECK_DECLS([loginfailed], [AC_MSG_CHECKING([if loginfailed takes 4 arguments]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ (void)loginfailed("user","host","tty",0); ]])], [AC_MSG_RESULT([yes]) AC_DEFINE([AIX_LOGINFAILED_4ARG], [1], [Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2)])], [AC_MSG_RESULT([no]) ])], [], [#include ] ) AC_CHECK_FUNCS([getgrset setauthdb]) AC_CHECK_DECL([F_CLOSEM], AC_DEFINE([HAVE_FCNTL_CLOSEM], [1], [Use F_CLOSEM fcntl for closefrom]), [], [ #include #include ] ) check_for_aix_broken_getaddrinfo=1 AC_DEFINE([BROKEN_REALPATH], [1], [Define if you have a broken realpath.]) AC_DEFINE([SETEUID_BREAKS_SETUID], [1], [Define if your platform breaks doing a seteuid before a setuid]) AC_DEFINE([BROKEN_SETREUID], [1], [Define if your setreuid() is broken]) AC_DEFINE([BROKEN_SETREGID], [1], [Define if your setregid() is broken]) dnl AIX handles lastlog as part of its login message AC_DEFINE([DISABLE_LASTLOG], [1], [Define if you don't want to use lastlog]) AC_DEFINE([LOGIN_NEEDS_UTMPX], [1], [Some systems need a utmpx entry for /bin/login to work]) AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV], [Define to a Set Process Title type if your system is supported by bsd-setproctitle.c]) AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1], [AIX 5.2 and 5.3 (and presumably newer) require this]) AC_DEFINE([PTY_ZEROREAD], [1], [read(1) can return 0 for a non-closed fd]) AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)]) ;; *-*-android*) AC_DEFINE([DISABLE_UTMP], [1], [Define if you don't want to use utmp]) AC_DEFINE([DISABLE_WTMP], [1], [Define if you don't want to use wtmp]) ;; *-*-cygwin*) check_for_libcrypt_later=1 LIBS="$LIBS /usr/lib/textreadmode.o" AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin]) AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()]) AC_DEFINE([NO_UID_RESTORATION_TEST], [1], [Define to disable UID restoration test]) AC_DEFINE([DISABLE_SHADOW], [1], [Define if you want to disable shadow passwords]) AC_DEFINE([NO_X11_UNIX_SOCKETS], [1], [Define if X11 doesn't support AF_UNIX sockets on that system]) AC_DEFINE([NO_IPPORT_RESERVED_CONCEPT], [1], [Define if the concept of ports only accessible to superusers isn't known]) AC_DEFINE([DISABLE_FD_PASSING], [1], [Define if your platform needs to skip post auth file descriptor passing]) AC_DEFINE([SSH_IOBUFSZ], [65535], [Windows is sensitive to read buffer size]) AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters]) # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes]) ;; *-*-dgux*) AC_DEFINE([IP_TOS_IS_BROKEN], [1], [Define if your system choked on IP TOS setting]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) ;; *-*-darwin*) use_pie=auto AC_MSG_CHECKING([if we have working getaddrinfo]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) exit(0); else exit(1); } ]])], [AC_MSG_RESULT([working])], [AC_MSG_RESULT([buggy]) AC_DEFINE([BROKEN_GETADDRINFO], [1], [getaddrinfo is broken (if present)]) ], [AC_MSG_RESULT([assume it is working])]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect]) AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1], [Define if your resolver libs need this for getrrsetbyname]) AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) AC_DEFINE([SSH_TUN_COMPAT_AF], [1], [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) [#include ] AC_DEFINE([LASTLOG_WRITE_PUTUTXLINE], [1], [Define if pututxline updates lastlog too]) ) AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV], [Define to a Set Process Title type if your system is supported by bsd-setproctitle.c]) AC_CHECK_FUNCS([sandbox_init]) AC_CHECK_HEADERS([sandbox.h]) AC_CHECK_LIB([sandbox], [sandbox_apply], [ SSHDLIBS="$SSHDLIBS -lsandbox" ]) ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-haiku*) LIBS="$LIBS -lbsd " AC_CHECK_LIB([network], [socket]) AC_DEFINE([HAVE_U_INT64_T]) MANTYPE=man ;; *-*-hpux*) # first we define all of the options common to all HP-UX releases CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" IPADDR_IN_DISPLAY=yes AC_DEFINE([USE_PIPES]) AC_DEFINE([LOGIN_NO_ENDOPT], [1], [Define if your login program cannot handle end of options ("--")]) AC_DEFINE([LOGIN_NEEDS_UTMPX]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*"], [String used in /etc/passwd to denote locked account]) AC_DEFINE([SPT_TYPE], [SPT_PSTAT]) AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)]) maildir="/var/mail" LIBS="$LIBS -lsec" AC_CHECK_LIB([xnet], [t_error], , [AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])]) # next, we define all of the options specific to major releases case "$host" in *-*-hpux10*) if test -z "$GCC"; then CFLAGS="$CFLAGS -Ae" fi ;; *-*-hpux11*) AC_DEFINE([PAM_SUN_CODEBASE], [1], [Define if you are using Solaris-derived PAM which passes pam_messages to the conversation function with an extra level of indirection]) AC_DEFINE([DISABLE_UTMP], [1], [Define if you don't want to use utmp]) AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins]) check_for_hpux_broken_getaddrinfo=1 check_for_conflicting_getspnam=1 ;; esac # lastly, we define options specific to minor releases case "$host" in *-*-hpux10.26) AC_DEFINE([HAVE_SECUREWARE], [1], [Define if you have SecureWare-based protected password database]) disable_ptmx_check=yes LIBS="$LIBS -lsecpw" ;; esac ;; *-*-irix5*) PATH="$PATH:/usr/etc" AC_DEFINE([BROKEN_INET_NTOA], [1], [Define if you system's inet_ntoa is busted (e.g. Irix gcc issue)]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([WITH_ABBREV_NO_TTY], [1], [Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) ;; *-*-irix6*) PATH="$PATH:/usr/etc" AC_DEFINE([WITH_IRIX_ARRAY], [1], [Define if you have/want arrays (cluster-wide session managment, not C arrays)]) AC_DEFINE([WITH_IRIX_PROJECT], [1], [Define if you want IRIX project management]) AC_DEFINE([WITH_IRIX_AUDIT], [1], [Define if you want IRIX audit trails]) AC_CHECK_FUNC([jlimit_startjob], [AC_DEFINE([WITH_IRIX_JOBS], [1], [Define if you want IRIX kernel jobs])]) AC_DEFINE([BROKEN_INET_NTOA]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([BROKEN_UPDWTMPX], [1], [updwtmpx is broken (if present)]) AC_DEFINE([WITH_ABBREV_NO_TTY]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) ;; *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) check_for_libcrypt_later=1 AC_DEFINE([PAM_TTY_KLUDGE]) AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"]) AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV]) AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins]) ;; *-*-linux*) no_dev_ptmx=1 use_pie=auto check_for_libcrypt_later=1 check_for_openpty_ctty_bug=1 AC_DEFINE([PAM_TTY_KLUDGE], [1], [Work around problematic Linux PAM modules handling of PAM_TTY]) AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"], [String used in /etc/passwd to denote locked account]) AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV]) AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM], [Define to whatever link() returns for "not supported" if it doesn't return EOPNOTSUPP.]) AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) AC_DEFINE([USE_BTMP]) AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) AC_DEFINE([BROKEN_CMSG_TYPE], [1], [Define if cmsg_type is not passed correctly]) ;; esac # tun(4) forwarding compat code AC_CHECK_HEADERS([linux/if_tun.h]) if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then AC_DEFINE([SSH_TUN_LINUX], [1], [Open tunnel devices the Linux tun/tap way]) AC_DEFINE([SSH_TUN_COMPAT_AF], [1], [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) fi AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h], [], [], [#include ]) AC_CHECK_FUNCS([prctl]) AC_MSG_CHECKING([for seccomp architecture]) seccomp_audit_arch= case "$host" in x86_64-*) seccomp_audit_arch=AUDIT_ARCH_X86_64 ;; i*86-*) seccomp_audit_arch=AUDIT_ARCH_I386 ;; arm*-*) seccomp_audit_arch=AUDIT_ARCH_ARM ;; aarch64*-*) seccomp_audit_arch=AUDIT_ARCH_AARCH64 ;; esac if test "x$seccomp_audit_arch" != "x" ; then AC_MSG_RESULT(["$seccomp_audit_arch"]) AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch], [Specify the system call convention in use]) else AC_MSG_RESULT([architecture not supported]) fi ;; mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to acquire controlling tty]) SONY=1 ;; *-*-netbsd*) check_for_libcrypt_before=1 if test "x$withval" != "xno" ; then need_dash_r=1 fi AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) AC_CHECK_HEADER([net/if_tap.h], , AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) TEST_MALLOC_OPTIONS="AJRX" AC_DEFINE([BROKEN_STRNVIS], [1], [NetBSD strnvis argument order is swapped compared to OpenBSD]) AC_DEFINE([BROKEN_READ_COMPARISON], [1], [NetBSD read function is sometimes redirected, breaking atomicio comparisons against it]) ;; *-*-freebsd*) check_for_libcrypt_later=1 AC_DEFINE([LOCKED_PASSWD_PREFIX], ["*LOCKED*"], [Account locked with pw(1)]) AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) AC_CHECK_HEADER([net/if_tap.h], , AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) AC_DEFINE([BROKEN_GLOB], [1], [FreeBSD glob does not do what we need]) AC_DEFINE([BROKEN_STRNVIS], [1], [FreeBSD strnvis argument order is swapped compared to OpenBSD]) TEST_MALLOC_OPTIONS="AJRX" # Preauth crypto occasionally uses file descriptors for crypto offload # and will crash if they cannot be opened. AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1], [define if setrlimit RLIMIT_NOFILE breaks things]) ;; *-*-bsdi*) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) ;; *-next-*) conf_lastlog_location="/usr/adm/lastlog" conf_utmp_location=/etc/utmp conf_wtmp_location=/usr/adm/wtmp maildir=/usr/spool/mail AC_DEFINE([HAVE_NEXT], [1], [Define if you are on NeXT]) AC_DEFINE([BROKEN_REALPATH]) AC_DEFINE([USE_PIPES]) AC_DEFINE([BROKEN_SAVED_UIDS], [1], [Needed for NeXT]) ;; *-*-openbsd*) use_pie=auto AC_DEFINE([HAVE_ATTRIBUTE__SENTINEL__], [1], [OpenBSD's gcc has sentinel]) AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD's gcc has bounded]) AC_DEFINE([SSH_TUN_OPENBSD], [1], [Open tunnel devices the OpenBSD way]) AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1], [syslog_r function is safe to use in in a signal handler]) TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-solaris*) if test "x$withval" != "xno" ; then need_dash_r=1 fi AC_DEFINE([PAM_SUN_CODEBASE]) AC_DEFINE([LOGIN_NEEDS_UTMPX]) AC_DEFINE([LOGIN_NEEDS_TERM], [1], [Some versions of /bin/login need the TERM supplied on the commandline]) AC_DEFINE([PAM_TTY_KLUDGE]) AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1], [Define if pam_chauthtok wants real uid set to the unpriv'ed user]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) # Pushing STREAMS modules will cause sshd to acquire a controlling tty. AC_DEFINE([SSHD_ACQUIRES_CTTY], [1], [Define if sshd somehow reacquires a controlling TTY after setsid()]) AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd in case the name is longer than 8 chars]) AC_DEFINE([BROKEN_TCGETATTR_ICANON], [1], [tcgetattr with ICANON may hang]) external_path_file=/etc/default/login # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" AC_MSG_CHECKING([for obsolete utmp and wtmp in solaris2.x]) sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'` if test "$sol2ver" -ge 8; then AC_MSG_RESULT([yes]) AC_DEFINE([DISABLE_UTMP]) AC_DEFINE([DISABLE_WTMP], [1], [Define if you don't want to use wtmp]) else AC_MSG_RESULT([no]) fi AC_CHECK_FUNCS([setppriv]) AC_CHECK_FUNCS([priv_basicset]) AC_CHECK_HEADERS([priv.h]) AC_ARG_WITH([solaris-contracts], [ --with-solaris-contracts Enable Solaris process contracts (experimental)], [ AC_CHECK_LIB([contract], [ct_tmpl_activate], [ AC_DEFINE([USE_SOLARIS_PROCESS_CONTRACTS], [1], [Define if you have Solaris process contracts]) LIBS="$LIBS -lcontract" SPC_MSG="yes" ], ) ], ) AC_ARG_WITH([solaris-projects], [ --with-solaris-projects Enable Solaris projects (experimental)], [ AC_CHECK_LIB([project], [setproject], [ AC_DEFINE([USE_SOLARIS_PROJECTS], [1], [Define if you have Solaris projects]) LIBS="$LIBS -lproject" SP_MSG="yes" ], ) ], ) AC_ARG_WITH([solaris-privs], [ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)], [ AC_MSG_CHECKING([for Solaris/Illumos privilege support]) if test "x$ac_cv_func_setppriv" = "xyes" -a \ "x$ac_cv_header_priv_h" = "xyes" ; then SOLARIS_PRIVS=yes AC_MSG_RESULT([found]) AC_DEFINE([NO_UID_RESTORATION_TEST], [1], [Define to disable UID restoration test]) AC_DEFINE([USE_SOLARIS_PRIVS], [1], [Define if you have Solaris privileges]) SPP_MSG="yes" else AC_MSG_RESULT([not found]) AC_MSG_ERROR([*** must have support for Solaris privileges to use --with-solaris-privs]) fi ], ) TEST_SHELL=$SHELL # let configure find us a capable shell ;; *-*-sunos4*) CPPFLAGS="$CPPFLAGS -DSUNOS4" AC_CHECK_FUNCS([getpwanam]) AC_DEFINE([PAM_SUN_CODEBASE]) conf_utmp_location=/etc/utmp conf_wtmp_location=/var/adm/wtmp conf_lastlog_location=/var/adm/lastlog AC_DEFINE([USE_PIPES]) ;; *-ncr-sysv*) LIBS="$LIBS -lc89" AC_DEFINE([USE_PIPES]) AC_DEFINE([SSHD_ACQUIRES_CTTY]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) ;; *-sni-sysv*) # /usr/ucblib MUST NOT be searched on ReliantUNIX AC_CHECK_LIB([dl], [dlsym], ,) # -lresolv needs to be at the end of LIBS or DNS lookups break AC_CHECK_LIB([resolv], [res_query], [ LIBS="$LIBS -lresolv" ]) IPADDR_IN_DISPLAY=yes AC_DEFINE([USE_PIPES]) AC_DEFINE([IP_TOS_IS_BROKEN]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([SSHD_ACQUIRES_CTTY]) external_path_file=/etc/default/login # /usr/ucblib/libucb.a no longer needed on ReliantUNIX # Attention: always take care to bind libsocket and libnsl before libc, # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog ;; # UnixWare 1.x, UnixWare 2.x, and others based on code from Univel. *-*-sysv4.2*) AC_DEFINE([USE_PIPES]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) TEST_SHELL=$SHELL # let configure find us a capable shell ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf" AC_DEFINE([UNIXWARE_LONG_PASSWORDS], [1], [Support passwords > 8 chars]) AC_DEFINE([USE_PIPES]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_GETADDRINFO]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([PASSWD_NEEDS_USERNAME]) TEST_SHELL=$SHELL # let configure find us a capable shell case "$host" in *-*-sysv5SCO_SV*) # SCO OpenServer 6.x maildir=/var/spool/mail AC_DEFINE([BROKEN_LIBIAF], [1], [ia_uinfo routines not supported by OS yet]) AC_DEFINE([BROKEN_UPDWTMPX]) AC_CHECK_LIB([prot], [getluid], [ LIBS="$LIBS -lprot" AC_CHECK_FUNCS([getluid setluid], , , [-lprot]) AC_DEFINE([HAVE_SECUREWARE]) AC_DEFINE([DISABLE_SHADOW]) ], , ) ;; *) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) check_for_libcrypt_later=1 ;; esac ;; *-*-sysv*) ;; # SCO UNIX and OEM versions of SCO UNIX *-*-sco3.2v4*) AC_MSG_ERROR("This Platform is no longer supported.") ;; # SCO OpenServer 5.x *-*-sco3.2v5*) if test -z "$GCC"; then CFLAGS="$CFLAGS -belf" fi LIBS="$LIBS -lprot -lx -ltinfo -lm" no_dev_ptmx=1 AC_DEFINE([USE_PIPES]) AC_DEFINE([HAVE_SECUREWARE]) AC_DEFINE([DISABLE_SHADOW]) AC_DEFINE([DISABLE_FD_PASSING]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_GETADDRINFO]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([WITH_ABBREV_NO_TTY]) AC_DEFINE([BROKEN_UPDWTMPX]) AC_DEFINE([PASSWD_NEEDS_USERNAME]) AC_CHECK_FUNCS([getluid setluid]) MANTYPE=man TEST_SHELL=$SHELL # let configure find us a capable shell SKIP_DISABLE_LASTLOG_DEFINE=yes ;; *-*-unicosmk*) AC_DEFINE([NO_SSH_LASTLOG], [1], [Define if you don't want to use lastlog in session.c]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([USE_PIPES]) AC_DEFINE([DISABLE_FD_PASSING]) LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-*-unicosmp*) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([WITH_ABBREV_NO_TTY]) AC_DEFINE([USE_PIPES]) AC_DEFINE([DISABLE_FD_PASSING]) LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lacid -ldb" MANTYPE=cat ;; *-*-unicos*) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([USE_PIPES]) AC_DEFINE([DISABLE_FD_PASSING]) AC_DEFINE([NO_SSH_LASTLOG]) LDFLAGS="$LDFLAGS -Wl,-Dmsglevel=334:fatal" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-dec-osf*) AC_MSG_CHECKING([for Digital Unix SIA]) no_osfsia="" AC_ARG_WITH([osfsia], [ --with-osfsia Enable Digital Unix SIA], [ if test "x$withval" = "xno" ; then AC_MSG_RESULT([disabled]) no_osfsia=1 fi ], ) if test -z "$no_osfsia" ; then if test -f /etc/sia/matrix.conf; then AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_OSF_SIA], [1], [Define if you have Digital Unix Security Integration Architecture]) AC_DEFINE([DISABLE_LOGIN], [1], [Define if you don't want to use your system's login() call]) AC_DEFINE([DISABLE_FD_PASSING]) LIBS="$LIBS -lsecurity -ldb -lm -laud" SIA_MSG="yes" else AC_MSG_RESULT([no]) AC_DEFINE([LOCKED_PASSWD_SUBSTR], ["Nologin"], [String used in /etc/passwd to denote locked account]) fi fi AC_DEFINE([BROKEN_GETADDRINFO]) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) AC_DEFINE([BROKEN_READV_COMPARISON], [1], [Can't do comparisons on readv]) ;; *-*-nto-qnx*) AC_DEFINE([USE_PIPES]) AC_DEFINE([NO_X11_UNIX_SOCKETS]) AC_DEFINE([DISABLE_LASTLOG]) AC_DEFINE([SSHD_ACQUIRES_CTTY]) AC_DEFINE([BROKEN_SHADOW_EXPIRE], [1], [QNX shadow support is broken]) enable_etc_default_login=no # has incompatible /etc/default/login case "$host" in *-*-nto-qnx6*) AC_DEFINE([DISABLE_FD_PASSING]) ;; esac ;; *-*-ultrix*) AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1]) AC_DEFINE([BROKEN_MMAP], [1], [Ultrix mmap can't map files]) AC_DEFINE([NEED_SETPGRP]) AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix]) ;; *-*-lynxos) CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" AC_DEFINE([BROKEN_SETVBUF], [1], [LynxOS has broken setvbuf() implementation]) ;; esac AC_MSG_CHECKING([compiler and flags for sanity]) AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) ], [ AC_MSG_WARN([cross compiling: not checking compiler sanity]) ] ) dnl Checks for header files. # Checks for libraries. AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])]) dnl IRIX and Solaris 2.5.1 have dirname() in libgen AC_CHECK_FUNCS([dirname], [AC_CHECK_HEADERS([libgen.h])] , [ AC_CHECK_LIB([gen], [dirname], [ AC_CACHE_CHECK([for broken dirname], ac_cv_have_broken_dirname, [ save_LIBS="$LIBS" LIBS="$LIBS -lgen" AC_RUN_IFELSE( [AC_LANG_SOURCE([[ #include #include int main(int argc, char **argv) { char *s, buf[32]; strncpy(buf,"/etc", 32); s = dirname(buf); if (!s || strncmp(s, "/", 32) != 0) { exit(1); } else { exit(0); } } ]])], [ ac_cv_have_broken_dirname="no" ], [ ac_cv_have_broken_dirname="yes" ], [ ac_cv_have_broken_dirname="no" ], ) LIBS="$save_LIBS" ]) if test "x$ac_cv_have_broken_dirname" = "xno" ; then LIBS="$LIBS -lgen" AC_DEFINE([HAVE_DIRNAME]) AC_CHECK_HEADERS([libgen.h]) fi ]) ]) AC_CHECK_FUNC([getspnam], , [AC_CHECK_LIB([gen], [getspnam], [LIBS="$LIBS -lgen"])]) AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1], [Define if you have the basename function.])]) dnl zlib is required AC_ARG_WITH([zlib], [ --with-zlib=PATH Use zlib in PATH], [ if test "x$withval" = "xno" ; then AC_MSG_ERROR([*** zlib is required ***]) elif test "x$withval" != "xyes"; then if test -d "$withval/lib"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi else if test -n "${need_dash_r}"; then LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" else LDFLAGS="-L${withval} ${LDFLAGS}" fi fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include ${CPPFLAGS}" else CPPFLAGS="-I${withval} ${CPPFLAGS}" fi fi ] ) AC_CHECK_HEADER([zlib.h], ,[AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***])]) AC_CHECK_LIB([z], [deflate], , [ saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" dnl Check default zlib install dir if test -n "${need_dash_r}"; then LDFLAGS="-L/usr/local/lib -R/usr/local/lib ${saved_LDFLAGS}" else LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}" fi CPPFLAGS="-I/usr/local/include ${saved_CPPFLAGS}" LIBS="$LIBS -lz" AC_TRY_LINK_FUNC([deflate], [AC_DEFINE([HAVE_LIBZ])], [ AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***]) ] ) ] ) AC_ARG_WITH([zlib-version-check], [ --without-zlib-version-check Disable zlib version check], [ if test "x$withval" = "xno" ; then zlib_check_nonfatal=1 fi ] ) AC_MSG_CHECKING([for possibly buggy zlib]) AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ int a=0, b=0, c=0, d=0, n, v; n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d); if (n != 3 && n != 4) exit(1); v = a*1000000 + b*10000 + c*100 + d; fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v); /* 1.1.4 is OK */ if (a == 1 && b == 1 && c >= 4) exit(0); /* 1.2.3 and up are OK */ if (v >= 1020300) exit(0); exit(2); ]])], AC_MSG_RESULT([no]), [ AC_MSG_RESULT([yes]) if test -z "$zlib_check_nonfatal" ; then AC_MSG_ERROR([*** zlib too old - check config.log *** Your reported zlib version has known security problems. It's possible your vendor has fixed these problems without changing the version number. If you are sure this is the case, you can disable the check by running "./configure --without-zlib-version-check". If you are in doubt, upgrade zlib to version 1.2.3 or greater. See http://www.gzip.org/zlib/ for details.]) else AC_MSG_WARN([zlib version may have security problems]) fi ], [ AC_MSG_WARN([cross compiling: not checking zlib version]) ] ) dnl UnixWare 2.x AC_CHECK_FUNC([strcasecmp], [], [ AC_CHECK_LIB([resolv], [strcasecmp], [LIBS="$LIBS -lresolv"]) ] ) AC_CHECK_FUNCS([utimes], [], [ AC_CHECK_LIB([c89], [utimes], [AC_DEFINE([HAVE_UTIMES]) LIBS="$LIBS -lc89"]) ] ) dnl Checks for libutil functions AC_CHECK_HEADERS([bsd/libutil.h libutil.h]) AC_SEARCH_LIBS([fmt_scaled], [util bsd]) AC_SEARCH_LIBS([scan_scaled], [util bsd]) AC_SEARCH_LIBS([login], [util bsd]) AC_SEARCH_LIBS([logout], [util bsd]) AC_SEARCH_LIBS([logwtmp], [util bsd]) AC_SEARCH_LIBS([openpty], [util bsd]) AC_SEARCH_LIBS([updwtmp], [util bsd]) AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp]) # On some platforms, inet_ntop and gethostbyname may be found in libresolv # or libnsl. AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) AC_SEARCH_LIBS([gethostbyname], [resolv nsl]) AC_FUNC_STRFTIME # Check for ALTDIRFUNC glob() extension AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support]) AC_EGREP_CPP([FOUNDIT], [ #include #ifdef GLOB_ALTDIRFUNC FOUNDIT #endif ], [ AC_DEFINE([GLOB_HAS_ALTDIRFUNC], [1], [Define if your system glob() function has the GLOB_ALTDIRFUNC extension]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ] ) # Check for g.gl_matchc glob() extension AC_MSG_CHECKING([for gl_matchc field in glob_t]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ glob_t g; g.gl_matchc = 1; ]])], [ AC_DEFINE([GLOB_HAS_GL_MATCHC], [1], [Define if your system glob() function has gl_matchc options in glob_t]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) # Check for g.gl_statv glob() extension AC_MSG_CHECKING([for gl_statv and GLOB_KEEPSTAT extensions for glob]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ #ifndef GLOB_KEEPSTAT #error "glob does not support GLOB_KEEPSTAT extension" #endif glob_t g; g.gl_statv = NULL; ]])], [ AC_DEFINE([GLOB_HAS_GL_STATV], [1], [Define if your system glob() function has gl_statv options in glob_t]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include ]) AC_MSG_CHECKING([whether struct dirent allocates space for d_name]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ struct dirent d; exit(sizeof(d.d_name)<=sizeof(char)); ]])], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME], [1], [Define if your struct dirent expects you to allocate extra space for d_name]) ], [ AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME]) AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME]) ] ) AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then AC_DEFINE([HAVE_PROC_PID], [1], [Define if you have /proc/$pid/fd]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi # Check whether user wants S/Key support SKEY_MSG="no" AC_ARG_WITH([skey], [ --with-skey[[=PATH]] Enable S/Key support (optionally in PATH)], [ if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" fi AC_DEFINE([SKEY], [1], [Define if you want S/Key support]) LIBS="-lskey $LIBS" SKEY_MSG="yes" AC_MSG_CHECKING([for s/key support]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ char *ff = skey_keyinfo(""); ff=""; exit(0); ]])], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([** Incomplete or missing s/key libraries.]) ]) AC_MSG_CHECKING([if skeychallenge takes 4 arguments]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ (void)skeychallenge(NULL,"name","",0); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([SKEYCHALLENGE_4ARG], [1], [Define if your skeychallenge() function takes 4 arguments (NetBSD)])], [ AC_MSG_RESULT([no]) ]) fi ] ) # Check whether user wants to use ldns LDNS_MSG="no" AC_ARG_WITH(ldns, [ --with-ldns[[=PATH]] Use ldns for DNSSEC support (optionally in PATH)], [ if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" fi AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support]) LIBS="-lldns $LIBS" LDNS_MSG="yes" AC_MSG_CHECKING([for ldns support]) AC_LINK_IFELSE( [AC_LANG_SOURCE([[ #include #include #include #include int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); } ]]) ], [AC_MSG_RESULT(yes)], [ AC_MSG_RESULT(no) AC_MSG_ERROR([** Incomplete or missing ldns libraries.]) ]) fi ] ) # Check whether user wants libedit support LIBEDIT_MSG="no" AC_ARG_WITH([libedit], [ --with-libedit[[=PATH]] Enable libedit support for sftp], [ if test "x$withval" != "xno" ; then if test "x$withval" = "xyes" ; then AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) if test "x$PKGCONFIG" != "xno"; then AC_MSG_CHECKING([if $PKGCONFIG knows about libedit]) if "$PKGCONFIG" libedit; then AC_MSG_RESULT([yes]) use_pkgconfig_for_libedit=yes else AC_MSG_RESULT([no]) fi fi else CPPFLAGS="$CPPFLAGS -I${withval}/include" if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi fi if test "x$use_pkgconfig_for_libedit" = "xyes"; then LIBEDIT=`$PKGCONFIG --libs libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else LIBEDIT="-ledit -lcurses" fi OTHERLIBS=`echo $LIBEDIT | sed 's/-ledit//'` AC_CHECK_LIB([edit], [el_init], [ AC_DEFINE([USE_LIBEDIT], [1], [Use libedit for sftp]) LIBEDIT_MSG="yes" AC_SUBST([LIBEDIT]) ], [ AC_MSG_ERROR([libedit not found]) ], [ $OTHERLIBS ] ) AC_MSG_CHECKING([if libedit version is compatible]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ int i = H_SETSIZE; el_init("", NULL, NULL, NULL); exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([libedit version is not compatible]) ] ) fi ] ) AUDIT_MODULE=none AC_ARG_WITH([audit], [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], [ AC_MSG_CHECKING([for supported audit module]) case "$withval" in bsm) AC_MSG_RESULT([bsm]) AUDIT_MODULE=bsm dnl Checks for headers, libs and functions AC_CHECK_HEADERS([bsm/audit.h], [], [AC_MSG_ERROR([BSM enabled and bsm/audit.h not found])], [ #ifdef HAVE_TIME_H # include #endif ] ) AC_CHECK_LIB([bsm], [getaudit], [], [AC_MSG_ERROR([BSM enabled and required library not found])]) AC_CHECK_FUNCS([getaudit], [], [AC_MSG_ERROR([BSM enabled and required function not found])]) # These are optional AC_CHECK_FUNCS([getaudit_addr aug_get_machine]) AC_DEFINE([USE_BSM_AUDIT], [1], [Use BSM audit module]) if test "$sol2ver" -ge 11; then SSHDLIBS="$SSHDLIBS -lscf" AC_DEFINE([BROKEN_BSM_API], [1], [The system has incomplete BSM API]) fi ;; linux) AC_MSG_RESULT([linux]) AUDIT_MODULE=linux dnl Checks for headers, libs and functions AC_CHECK_HEADERS([libaudit.h]) SSHDLIBS="$SSHDLIBS -laudit" AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module]) ;; debug) AUDIT_MODULE=debug AC_MSG_RESULT([debug]) AC_DEFINE([SSH_AUDIT_EVENTS], [1], [Use audit debugging module]) ;; no) AC_MSG_RESULT([no]) ;; *) AC_MSG_ERROR([Unknown audit module $withval]) ;; esac ] ) AC_ARG_WITH([pie], [ --with-pie Build Position Independent Executables if possible], [ if test "x$withval" = "xno"; then use_pie=no fi if test "x$withval" = "xyes"; then use_pie=yes fi ] ) if test "x$use_pie" = "x"; then use_pie=no fi if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then # Turn off automatic PIE when toolchain hardening is off. use_pie=no fi if test "x$use_pie" = "xauto"; then # Automatic PIE requires gcc >= 4.x AC_MSG_CHECKING([for gcc >= 4.x]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #if !defined(__GNUC__) || __GNUC__ < 4 #error gcc is too old #endif ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) use_pie=no ] ) fi if test "x$use_pie" != "xno"; then SAVED_CFLAGS="$CFLAGS" SAVED_LDFLAGS="$LDFLAGS" OSSH_CHECK_CFLAG_COMPILE([-fPIE]) OSSH_CHECK_LDFLAG_LINK([-pie]) # We use both -fPIE and -pie or neither. AC_MSG_CHECKING([whether both -fPIE and -pie are supported]) if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \ echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) CFLAGS="$SAVED_CFLAGS" LDFLAGS="$SAVED_LDFLAGS" fi fi dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ Blowfish_initstate \ Blowfish_expandstate \ Blowfish_expand0state \ Blowfish_stream2word \ asprintf \ b64_ntop \ __b64_ntop \ b64_pton \ __b64_pton \ bcopy \ bcrypt_pbkdf \ bindresvport_sa \ blf_enc \ cap_rights_limit \ clock \ closefrom \ dirfd \ endgrent \ explicit_bzero \ fchmod \ fchown \ freeaddrinfo \ fstatfs \ fstatvfs \ futimes \ getaddrinfo \ getcwd \ getgrouplist \ getnameinfo \ getopt \ getpeereid \ getpeerucred \ getpgid \ getpgrp \ _getpty \ getrlimit \ getttyent \ glob \ group_from_gid \ inet_aton \ inet_ntoa \ inet_ntop \ innetgr \ login_getcapbool \ mblen \ md5_crypt \ memmove \ memset_s \ mkdtemp \ mmap \ ngetaddrinfo \ nsleep \ ogetaddrinfo \ openlog_r \ pledge \ poll \ prctl \ pstat \ readpassphrase \ reallocarray \ recvmsg \ rresvport_af \ sendmsg \ setdtablesize \ setegid \ setenv \ seteuid \ setgroupent \ setgroups \ setlinebuf \ setlogin \ setpassent\ setpcred \ setproctitle \ setregid \ setreuid \ setrlimit \ setsid \ setvbuf \ sigaction \ sigvec \ snprintf \ socketpair \ statfs \ statvfs \ strdup \ strerror \ strlcat \ strlcpy \ strmode \ strnlen \ strnvis \ strptime \ strtonum \ strtoll \ strtoul \ strtoull \ swap32 \ sysconf \ tcgetpgrp \ timingsafe_bcmp \ truncate \ unsetenv \ updwtmpx \ user_from_uid \ usleep \ vasprintf \ vsnprintf \ waitpid \ ]) AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ return (isblank('a')); ]])], [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) # PKCS11 depends on OpenSSL. if test "x$openssl" = "xyes" ; then # PKCS#11 support requires dlopen() and co AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] ) fi # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include const char *gai_strerror(int); ]], [[ char *str; str = gai_strerror(0); ]])], [ AC_DEFINE([HAVE_CONST_GAI_STRERROR_PROTO], [1], [Define if gai_strerror() returns const char *])], [])]) AC_SEARCH_LIBS([nanosleep], [rt posix4], [AC_DEFINE([HAVE_NANOSLEEP], [1], [Some systems put nanosleep outside of libc])]) AC_SEARCH_LIBS([clock_gettime], [rt], [AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Have clock_gettime])]) dnl Make sure prototypes are defined for these before using them. AC_CHECK_DECL([getrusage], [AC_CHECK_FUNCS([getrusage])]) AC_CHECK_DECL([strsep], [AC_CHECK_FUNCS([strsep])], [], [ #ifdef HAVE_STRING_H # include #endif ]) dnl tcsendbreak might be a macro AC_CHECK_DECL([tcsendbreak], [AC_DEFINE([HAVE_TCSENDBREAK])], [AC_CHECK_FUNCS([tcsendbreak])], [#include ] ) AC_CHECK_DECLS([h_errno], , ,[#include ]) AC_CHECK_DECLS([SHUT_RD], , , [ #include #include ]) AC_CHECK_DECLS([O_NONBLOCK], , , [ #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif ]) AC_CHECK_DECLS([writev], , , [ #include #include #include ]) AC_CHECK_DECLS([MAXSYMLINKS], , , [ #include ]) AC_CHECK_DECLS([offsetof], , , [ #include ]) # extra bits for select(2) AC_CHECK_DECLS([howmany, NFDBITS], [], [], [[ #include #include #ifdef HAVE_SYS_SYSMACROS_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif ]]) AC_CHECK_TYPES([fd_mask], [], [], [[ #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif ]]) AC_CHECK_FUNCS([setresuid], [ dnl Some platorms have setresuid that isn't implemented, test for this AC_MSG_CHECKING([if setresuid seems to work]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ]])], [AC_MSG_RESULT([yes])], [AC_DEFINE([BROKEN_SETRESUID], [1], [Define if your setresuid() is broken]) AC_MSG_RESULT([not implemented])], [AC_MSG_WARN([cross compiling: not checking setresuid])] ) ]) AC_CHECK_FUNCS([setresgid], [ dnl Some platorms have setresgid that isn't implemented, test for this AC_MSG_CHECKING([if setresgid seems to work]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ]])], [AC_MSG_RESULT([yes])], [AC_DEFINE([BROKEN_SETRESGID], [1], [Define if your setresgid() is broken]) AC_MSG_RESULT([not implemented])], [AC_MSG_WARN([cross compiling: not checking setresuid])] ) ]) AC_CHECK_FUNCS([realpath], [ dnl the sftp v3 spec says SSH_FXP_REALPATH will "canonicalize any given dnl path name", however some implementations of realpath (and some dnl versions of the POSIX spec) do not work on non-existent files, dnl so we use the OpenBSD implementation on those platforms. AC_MSG_CHECKING([if realpath works with non-existent files]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include ]], [[ char buf[PATH_MAX]; if (realpath("/opensshnonexistentfilename1234", buf) == NULL) if (errno == ENOENT) exit(1); exit(0); ]])], [AC_MSG_RESULT([yes])], [AC_DEFINE([BROKEN_REALPATH], [1], [realpath does not work with nonexistent files]) AC_MSG_RESULT([no])], [AC_MSG_WARN([cross compiling: assuming working])] ) ]) dnl Checks for time functions AC_CHECK_FUNCS([gettimeofday time]) dnl Checks for utmp functions AC_CHECK_FUNCS([endutent getutent getutid getutline pututline setutent]) AC_CHECK_FUNCS([utmpname]) dnl Checks for utmpx functions AC_CHECK_FUNCS([endutxent getutxent getutxid getutxline getutxuser pututxline]) AC_CHECK_FUNCS([setutxdb setutxent utmpxname]) dnl Checks for lastlog functions AC_CHECK_FUNCS([getlastlogxbyname]) AC_CHECK_FUNC([daemon], [AC_DEFINE([HAVE_DAEMON], [1], [Define if your libraries define daemon()])], [AC_CHECK_LIB([bsd], [daemon], [LIBS="$LIBS -lbsd"; AC_DEFINE([HAVE_DAEMON])])] ) AC_CHECK_FUNC([getpagesize], [AC_DEFINE([HAVE_GETPAGESIZE], [1], [Define if your libraries define getpagesize()])], [AC_CHECK_LIB([ucb], [getpagesize], [LIBS="$LIBS -lucb"; AC_DEFINE([HAVE_GETPAGESIZE])])] ) # Check for broken snprintf if test "x$ac_cv_func_snprintf" = "xyes" ; then AC_MSG_CHECKING([whether snprintf correctly terminates long strings]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ char b[5]; snprintf(b,5,"123456789"); exit(b[4]!='\0'); ]])], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_SNPRINTF], [1], [Define if your snprintf is busted]) AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) ], [ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ] ) fi # We depend on vsnprintf returning the right thing on overflow: the # number of characters it tried to create (as per SUSv3) if test "x$ac_cv_func_vsnprintf" = "xyes" ; then AC_MSG_CHECKING([whether vsnprintf returns correct values on overflow]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include int x_snprintf(char *str, size_t count, const char *fmt, ...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } ]], [[ char x[1]; if (x_snprintf(x, 1, "%s %d", "hello", 12345) != 11) return 1; if (x_snprintf(NULL, 0, "%s %d", "hello", 12345) != 11) return 1; return 0; ]])], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_SNPRINTF], [1], [Define if your snprintf is busted]) AC_MSG_WARN([****** Your vsnprintf() function is broken, complain to your vendor]) ], [ AC_MSG_WARN([cross compiling: Assuming working vsnprintf()]) ] ) fi # On systems where [v]snprintf is broken, but is declared in stdio, # check that the fmt argument is const char * or just char *. # This is only useful for when BROKEN_SNPRINTF AC_MSG_CHECKING([whether snprintf can declare const char *fmt]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } ]], [[ snprintf(0, 0, 0); ]])], [AC_MSG_RESULT([yes]) AC_DEFINE([SNPRINTF_CONST], [const], [Define as const if snprintf() can declare const char *fmt])], [AC_MSG_RESULT([no]) AC_DEFINE([SNPRINTF_CONST], [/* not const */])]) # Check for missing getpeereid (or equiv) support NO_PEERCHECK="" if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[int i = SO_PEERCRED;]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_SO_PEERCRED], [1], [Have PEERCRED socket option]) ], [AC_MSG_RESULT([no]) NO_PEERCHECK=1 ]) fi dnl see whether mkstemp() requires XXXXXX if test "x$ac_cv_func_mkdtemp" = "xyes" ; then AC_MSG_CHECKING([for (overly) strict mkstemp]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ char template[]="conftest.mkstemp-test"; if (mkstemp(template) == -1) exit(1); unlink(template); exit(0); ]])], [ AC_MSG_RESULT([no]) ], [ AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_STRICT_MKSTEMP], [1], [Silly mkstemp()]) ], [ AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_STRICT_MKSTEMP]) ] ) fi dnl make sure that openpty does not reacquire controlling terminal if test ! -z "$check_for_openpty_ctty_bug"; then AC_MSG_CHECKING([if openpty correctly handles controlling tty]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include ]], [[ pid_t pid; int fd, ptyfd, ttyfd, status; pid = fork(); if (pid < 0) { /* failed */ exit(1); } else if (pid > 0) { /* parent */ waitpid(pid, &status, 0); if (WIFEXITED(status)) exit(WEXITSTATUS(status)); else exit(2); } else { /* child */ close(0); close(1); close(2); setsid(); openpty(&ptyfd, &ttyfd, NULL, NULL, NULL); fd = open("/dev/tty", O_RDWR | O_NOCTTY); if (fd >= 0) exit(3); /* Acquired ctty: broken */ else exit(0); /* Did not acquire ctty: OK */ } ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_DEFINE([SSHD_ACQUIRES_CTTY]) ], [ AC_MSG_RESULT([cross-compiling, assuming yes]) ] ) fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then AC_MSG_CHECKING([if getaddrinfo seems to work]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #define TEST_PORT "2222" ]], [[ int err, sock; struct addrinfo *gai_ai, *ai, hints; char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); if (err != 0) { fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); exit(1); } for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET6) continue; err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV); if (err != 0) { if (err == EAI_SYSTEM) perror("getnameinfo EAI_SYSTEM"); else fprintf(stderr, "getnameinfo failed: %s\n", gai_strerror(err)); exit(2); } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) perror("socket"); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { if (errno == EBADF) exit(3); } } exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_GETADDRINFO]) ], [ AC_MSG_RESULT([cross-compiling, assuming yes]) ] ) fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_aix_broken_getaddrinfo" = "x1"; then AC_MSG_CHECKING([if getaddrinfo seems to work]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #define TEST_PORT "2222" ]], [[ int err, sock; struct addrinfo *gai_ai, *ai, hints; char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); if (err != 0) { fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); exit(1); } for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV); if (ai->ai_family == AF_INET && err != 0) { perror("getnameinfo"); exit(2); } } exit(0); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([AIX_GETNAMEINFO_HACK], [1], [Define if you have a getaddrinfo that fails for the all-zeros IPv6 address]) ], [ AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_GETADDRINFO]) ], [ AC_MSG_RESULT([cross-compiling, assuming no]) ] ) fi if test "x$ac_cv_func_getaddrinfo" = "xyes"; then AC_CHECK_DECLS(AI_NUMERICSERV, , , [#include #include #include ]) fi if test "x$check_for_conflicting_getspnam" = "x1"; then AC_MSG_CHECKING([for conflicting getspnam in shadow.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], [ AC_MSG_RESULT([no]) ], [ AC_MSG_RESULT([yes]) AC_DEFINE([GETSPNAM_CONFLICTING_DEFS], [1], [Conflicting defs for getspnam]) ] ) fi AC_FUNC_GETPGRP # Search for OpenSSL saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" AC_ARG_WITH([ssl-dir], [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], [ if test "x$openssl" = "xno" ; then AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled]) fi if test "x$withval" != "xno" ; then case "$withval" in # Relative paths ./*|../*) withval="`pwd`/$withval" esac if test -d "$withval/lib"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi elif test -d "$withval/lib64"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib64 -R${withval}/lib64 ${LDFLAGS}" else LDFLAGS="-L${withval}/lib64 ${LDFLAGS}" fi else if test -n "${need_dash_r}"; then LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" else LDFLAGS="-L${withval} ${LDFLAGS}" fi fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include ${CPPFLAGS}" else CPPFLAGS="-I${withval} ${CPPFLAGS}" fi fi ] ) AC_ARG_WITH([openssl-header-check], [ --without-openssl-header-check Disable OpenSSL version consistency check], [ if test "x$withval" = "xno" ; then openssl_check_nonfatal=1 fi ] ) openssl_engine=no AC_ARG_WITH([ssl-engine], [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], [ if test "x$withval" != "xno" ; then if test "x$openssl" = "xno" ; then AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled]) fi openssl_engine=yes fi ] ) if test "x$openssl" = "xyes" ; then LIBS="-lcrypto $LIBS" AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], [Define if your ssl headers are included with #include ])], [ dnl Check default openssl install dir if test -n "${need_dash_r}"; then LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" else LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" fi CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" AC_CHECK_HEADER([openssl/opensslv.h], , [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])], [ AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***]) ] ) ] ) # Determine OpenSSL header version AC_MSG_CHECKING([OpenSSL header version]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #define DATA "conftest.sslincver" ]], [[ FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd ,"%08lx (%s)\n", (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) exit(1); exit(0); ]])], [ ssl_header_ver=`cat conftest.sslincver` AC_MSG_RESULT([$ssl_header_ver]) ], [ AC_MSG_RESULT([not found]) AC_MSG_ERROR([OpenSSL version header not found.]) ], [ AC_MSG_WARN([cross compiling: not checking]) ] ) # Determine OpenSSL library version AC_MSG_CHECKING([OpenSSL library version]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #define DATA "conftest.ssllibver" ]], [[ FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0) exit(1); exit(0); ]])], [ ssl_library_ver=`cat conftest.ssllibver` # Check version is supported. case "$ssl_library_ver" in 0090[[0-7]]*|009080[[0-5]]*) AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")]) ;; *) ;; esac AC_MSG_RESULT([$ssl_library_ver]) ], [ AC_MSG_RESULT([not found]) AC_MSG_ERROR([OpenSSL library not found.]) ], [ AC_MSG_WARN([cross compiling: not checking]) ] ) # Sanity check OpenSSL headers AC_MSG_CHECKING([whether OpenSSL's headers match the library]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include ]], [[ exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) if test "x$openssl_check_nonfatal" = "x"; then AC_MSG_ERROR([Your OpenSSL headers do not match your library. Check config.log for details. If you are sure your installation is consistent, you can disable the check by running "./configure --without-openssl-header-check". Also see contrib/findssl.sh for help identifying header/library mismatches. ]) else AC_MSG_WARN([Your OpenSSL headers do not match your library. Check config.log for details. Also see contrib/findssl.sh for help identifying header/library mismatches.]) fi ], [ AC_MSG_WARN([cross compiling: not checking]) ] ) AC_MSG_CHECKING([if programs using OpenSSL functions will link]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ SSLeay_add_all_algorithms(); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) saved_LIBS="$LIBS" LIBS="$LIBS -ldl" AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ SSLeay_add_all_algorithms(); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) LIBS="$saved_LIBS" ] ) ] ) AC_CHECK_FUNCS([ \ BN_is_prime_ex \ DSA_generate_parameters_ex \ EVP_DigestInit_ex \ EVP_DigestFinal_ex \ EVP_MD_CTX_init \ EVP_MD_CTX_cleanup \ EVP_MD_CTX_copy_ex \ HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ ]) if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([USE_OPENSSL_ENGINE], [1], [Enable OpenSSL engine support]) ], [ AC_MSG_ERROR([OpenSSL ENGINE support not found]) ]) fi # Check for OpenSSL without EVP_aes_{192,256}_cbc AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ]])], [ AC_MSG_RESULT([no]) ], [ AC_MSG_RESULT([yes]) AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1], [libcrypto is missing AES 192 and 256 bit functions]) ] ) # Check for OpenSSL with EVP_aes_*ctr AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ exit(EVP_aes_128_ctr() == NULL || EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], [libcrypto has EVP AES CTR]) ], [ AC_MSG_RESULT([no]) ] ) # Check for OpenSSL with EVP_aes_*gcm AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ exit(EVP_aes_128_gcm() == NULL || EVP_aes_256_gcm() == NULL || EVP_CTRL_GCM_SET_IV_FIXED == 0 || EVP_CTRL_GCM_IV_GEN == 0 || EVP_CTRL_GCM_SET_TAG == 0 || EVP_CTRL_GCM_GET_TAG == 0 || EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], [libcrypto has EVP AES GCM]) ], [ AC_MSG_RESULT([no]) unsupported_algorithms="$unsupported_cipers \ aes128-gcm@openssh.com aes256-gcm@openssh.com" ] ) AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto], [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1], [Define if libcrypto has EVP_CIPHER_CTX_ctrl])]) AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ if(EVP_DigestUpdate(NULL, NULL,0)) exit(0); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1], [Define if EVP_DigestUpdate returns void]) ] ) # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, # because the system crypt() is more featureful. if test "x$check_for_libcrypt_before" = "x1"; then AC_CHECK_LIB([crypt], [crypt]) fi # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the # version in OpenSSL. if test "x$check_for_libcrypt_later" = "x1"; then AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) fi AC_CHECK_FUNCS([crypt DES_crypt]) # Search for SHA256 support in libc and/or OpenSSL AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , [unsupported_algorithms="$unsupported_algorithms \ hmac-sha2-256 hmac-sha2-512 \ diffie-hellman-group-exchange-sha256 \ hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" ] ) # Search for RIPE-MD support in OpenSSL AC_CHECK_FUNCS([EVP_ripemd160], , [unsupported_algorithms="$unsupported_algorithms \ hmac-ripemd160 hmac-ripemd160@openssh.com hmac-ripemd160-etm@openssh.com" ] ) # Check complete ECC support in OpenSSL AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif ]], [[ EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); const EVP_MD *m = EVP_sha256(); /* We need this too */ ]])], [ AC_MSG_RESULT([yes]) enable_nistp256=1 ], [ AC_MSG_RESULT([no]) ] ) AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif ]], [[ EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); const EVP_MD *m = EVP_sha384(); /* We need this too */ ]])], [ AC_MSG_RESULT([yes]) enable_nistp384=1 ], [ AC_MSG_RESULT([no]) ] ) AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif ]], [[ EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ ]])], [ AC_MSG_RESULT([yes]) AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include #include #include ]],[[ EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ exit(e == NULL || m == NULL); ]])], [ AC_MSG_RESULT([yes]) enable_nistp521=1 ], [ AC_MSG_RESULT([no]) ], [ AC_MSG_WARN([cross-compiling: assuming yes]) enable_nistp521=1 ] )], AC_MSG_RESULT([no]) ) COMMENT_OUT_ECC="#no ecc#" TEST_SSH_ECC=no if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ test x$enable_nistp521 = x1; then AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) fi if test x$enable_nistp256 = x1; then AC_DEFINE([OPENSSL_HAS_NISTP256], [1], [libcrypto has NID_X9_62_prime256v1]) TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" fi if test x$enable_nistp384 = x1; then AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" fi if test x$enable_nistp521 = x1; then AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" fi AC_SUBST([TEST_SSH_ECC]) AC_SUBST([COMMENT_OUT_ECC]) else AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) AC_CHECK_FUNCS([crypt]) fi AC_CHECK_FUNCS([ \ arc4random \ arc4random_buf \ arc4random_stir \ arc4random_uniform \ ]) saved_LIBS="$LIBS" AC_CHECK_LIB([iaf], [ia_openinfo], [ LIBS="$LIBS -liaf" AC_CHECK_FUNCS([set_id], [SSHDLIBS="$SSHDLIBS -liaf" AC_DEFINE([HAVE_LIBIAF], [1], [Define if system has libiaf that supports set_id]) ]) ]) LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself if test "x$openssl" = "xyes" ; then AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ exit(RAND_status() == 1 ? 0 : 1); ]])], [ OPENSSL_SEEDS_ITSELF=yes AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ], [ AC_MSG_WARN([cross compiling: assuming yes]) # This is safe, since we will fatal() at runtime if # OpenSSL is not seeded correctly. OPENSSL_SEEDS_ITSELF=yes ] ) fi # PRNGD TCP socket AC_ARG_WITH([prngd-port], [ --with-prngd-port=PORT read entropy from PRNGD/EGD TCP localhost:PORT], [ case "$withval" in no) withval="" ;; [[0-9]]*) ;; *) AC_MSG_ERROR([You must specify a numeric port number for --with-prngd-port]) ;; esac if test ! -z "$withval" ; then PRNGD_PORT="$withval" AC_DEFINE_UNQUOTED([PRNGD_PORT], [$PRNGD_PORT], [Port number of PRNGD/EGD random number socket]) fi ] ) # PRNGD Unix domain socket AC_ARG_WITH([prngd-socket], [ --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)], [ case "$withval" in yes) withval="/var/run/egd-pool" ;; no) withval="" ;; /*) ;; *) AC_MSG_ERROR([You must specify an absolute path to the entropy socket]) ;; esac if test ! -z "$withval" ; then if test ! -z "$PRNGD_PORT" ; then AC_MSG_ERROR([You may not specify both a PRNGD/EGD port and socket]) fi if test ! -r "$withval" ; then AC_MSG_WARN([Entropy socket is not readable]) fi PRNGD_SOCKET="$withval" AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"], [Location of PRNGD/EGD random number socket]) fi ], [ # Check for existing socket only if we don't have a random device already if test "x$OPENSSL_SEEDS_ITSELF" != "xyes" ; then AC_MSG_CHECKING([for PRNGD/EGD socket]) # Insert other locations here for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then PRNGD_SOCKET="$sock" AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"]) break; fi done if test ! -z "$PRNGD_SOCKET" ; then AC_MSG_RESULT([$PRNGD_SOCKET]) else AC_MSG_RESULT([not found]) fi fi ] ) # Which randomness source do we use? if test ! -z "$PRNGD_PORT" ; then RAND_MSG="PRNGd port $PRNGD_PORT" elif test ! -z "$PRNGD_SOCKET" ; then RAND_MSG="PRNGd socket $PRNGD_SOCKET" elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then AC_DEFINE([OPENSSL_PRNG_ONLY], [1], [Define if you want the OpenSSL internally seeded PRNG only]) RAND_MSG="OpenSSL internal ONLY" elif test "x$openssl" = "xno" ; then AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible]) else AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options]) fi # Check for PAM libs PAM_MSG="no" AC_ARG_WITH([pam], [ --with-pam Enable PAM support ], [ if test "x$withval" != "xno" ; then if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \ test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then AC_MSG_ERROR([PAM headers not found]) fi saved_LIBS="$LIBS" AC_CHECK_LIB([dl], [dlopen], , ) AC_CHECK_LIB([pam], [pam_set_item], , [AC_MSG_ERROR([*** libpam missing])]) AC_CHECK_FUNCS([pam_getenvlist]) AC_CHECK_FUNCS([pam_putenv]) LIBS="$saved_LIBS" PAM_MSG="yes" SSHDLIBS="$SSHDLIBS -lpam" AC_DEFINE([USE_PAM], [1], [Define if you want to enable PAM support]) if test $ac_cv_lib_dl_dlopen = yes; then case "$LIBS" in *-ldl*) # libdl already in LIBS ;; *) SSHDLIBS="$SSHDLIBS -ldl" ;; esac fi fi ] ) # Check for older PAM if test "x$PAM_MSG" = "xyes" ; then # Check PAM strerror arguments (old PAM) AC_MSG_CHECKING([whether pam_strerror takes only one argument]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(HAVE_SECURITY_PAM_APPL_H) #include #elif defined (HAVE_PAM_PAM_APPL_H) #include #endif ]], [[ (void)pam_strerror((pam_handle_t *)NULL, -1); ]])], [AC_MSG_RESULT([no])], [ AC_DEFINE([HAVE_OLD_PAM], [1], [Define if you have an old version of PAM which takes only one argument to pam_strerror]) AC_MSG_RESULT([yes]) PAM_MSG="yes (old library)" ]) fi case "$host" in *-*-cygwin*) SSH_PRIVSEP_USER=CYGWIN_SSH_PRIVSEP_USER ;; *) SSH_PRIVSEP_USER=sshd ;; esac AC_ARG_WITH([privsep-user], [ --with-privsep-user=user Specify non-privileged user for privilege separation], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then SSH_PRIVSEP_USER=$withval fi ] ) if test "x$SSH_PRIVSEP_USER" = "xCYGWIN_SSH_PRIVSEP_USER" ; then AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], [CYGWIN_SSH_PRIVSEP_USER], [Cygwin function to fetch non-privileged user for privilege separation]) else AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], ["$SSH_PRIVSEP_USER"], [non-privileged user for privilege separation]) fi AC_SUBST([SSH_PRIVSEP_USER]) if test "x$have_linux_no_new_privs" = "x1" ; then AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [ #include #include ]) fi if test "x$have_seccomp_filter" = "x1" ; then AC_MSG_CHECKING([kernel for seccomp_filter support]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include #include #include #include ]], [[ int i = $seccomp_audit_arch; errno = 0; prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); exit(errno == EFAULT ? 0 : 1); ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) # Disable seccomp filter as a target have_seccomp_filter=0 ] ) fi # Decide which sandbox style to use sandbox_arg="" AC_ARG_WITH([sandbox], [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" else sandbox_arg="$withval" fi ] ) # Some platforms (seems to be the ones that have a kernel poll(2)-type # function with which they implement select(2)) use an extra file descriptor # when calling select(2), which means we can't use the rlimit sandbox. AC_MSG_CHECKING([if select works with descriptor rlimit]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #ifdef HAVE_SYS_TIME_H # include #endif #include #ifdef HAVE_SYS_SELECT_H # include #endif #include #include #include ]],[[ struct rlimit rl_zero; int fd, r; fd_set fds; struct timeval tv; fd = open("/dev/null", O_RDONLY); FD_ZERO(&fds); FD_SET(fd, &fds); rl_zero.rlim_cur = rl_zero.rlim_max = 0; setrlimit(RLIMIT_FSIZE, &rl_zero); setrlimit(RLIMIT_NOFILE, &rl_zero); tv.tv_sec = 1; tv.tv_usec = 0; r = select(fd+1, &fds, NULL, NULL, &tv); exit (r == -1 ? 1 : 0); ]])], [AC_MSG_RESULT([yes]) select_works_with_rlimit=yes], [AC_MSG_RESULT([no]) select_works_with_rlimit=no], [AC_MSG_WARN([cross compiling: assuming yes])] ) AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include ]],[[ struct rlimit rl_zero; int fd, r; fd_set fds; rl_zero.rlim_cur = rl_zero.rlim_max = 0; r = setrlimit(RLIMIT_NOFILE, &rl_zero); exit (r == -1 ? 1 : 0); ]])], [AC_MSG_RESULT([yes]) rlimit_nofile_zero_works=yes], [AC_MSG_RESULT([no]) rlimit_nofile_zero_works=no], [AC_MSG_WARN([cross compiling: assuming yes])] ) AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include ]],[[ struct rlimit rl_zero; rl_zero.rlim_cur = rl_zero.rlim_max = 0; exit(setrlimit(RLIMIT_FSIZE, &rl_zero) != 0); ]])], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_DEFINE(SANDBOX_SKIP_RLIMIT_FSIZE, 1, [setrlimit RLIMIT_FSIZE works])], [AC_MSG_WARN([cross compiling: assuming yes])] ) if test "x$sandbox_arg" = "xpledge" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then test "x$ac_cv_func_pledge" != "xyes" && \ AC_MSG_ERROR([pledge sandbox requires pledge(2) support]) SANDBOX_STYLE="pledge" AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)]) elif test "x$sandbox_arg" = "xsystrace" || \ ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then test "x$have_systr_policy_kill" != "x1" && \ AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support]) SANDBOX_STYLE="systrace" AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)]) elif test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ "x$ac_cv_header_sandbox_h" != "xyes" && \ AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function]) SANDBOX_STYLE="darwin" AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)]) elif test "x$sandbox_arg" = "xseccomp_filter" || \ ( test -z "$sandbox_arg" && \ test "x$have_seccomp_filter" = "x1" && \ test "x$ac_cv_header_elf_h" = "xyes" && \ test "x$ac_cv_header_linux_audit_h" = "xyes" && \ test "x$ac_cv_header_linux_filter_h" = "xyes" && \ test "x$seccomp_audit_arch" != "x" && \ test "x$have_linux_no_new_privs" = "x1" && \ test "x$ac_cv_func_prctl" = "xyes" ) ; then test "x$seccomp_audit_arch" = "x" && \ AC_MSG_ERROR([seccomp_filter sandbox not supported on $host]) test "x$have_linux_no_new_privs" != "x1" && \ AC_MSG_ERROR([seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS]) test "x$have_seccomp_filter" != "x1" && \ AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers]) test "x$ac_cv_func_prctl" != "xyes" && \ AC_MSG_ERROR([seccomp_filter sandbox requires prctl function]) SANDBOX_STYLE="seccomp_filter" AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter]) elif test "x$sandbox_arg" = "xcapsicum" || \ ( test -z "$sandbox_arg" && \ test "x$ac_cv_header_sys_capability_h" = "xyes" && \ test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then test "x$ac_cv_header_sys_capability_h" != "xyes" && \ AC_MSG_ERROR([capsicum sandbox requires sys/capability.h header]) test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function]) SANDBOX_STYLE="capsicum" AC_DEFINE([SANDBOX_CAPSICUM], [1], [Sandbox using capsicum]) elif test "x$sandbox_arg" = "xrlimit" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \ test "x$select_works_with_rlimit" = "xyes" && \ test "x$rlimit_nofile_zero_works" = "xyes" ) ; then test "x$ac_cv_func_setrlimit" != "xyes" && \ AC_MSG_ERROR([rlimit sandbox requires setrlimit function]) test "x$select_works_with_rlimit" != "xyes" && \ AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit]) SANDBOX_STYLE="rlimit" AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) elif test "x$sandbox_arg" = "xsolaris" || \ ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then SANDBOX_STYLE="solaris" AC_DEFINE([SANDBOX_SOLARIS], [1], [Sandbox using Solaris/Illumos privileges]) elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then SANDBOX_STYLE="none" AC_DEFINE([SANDBOX_NULL], [1], [no privsep sandboxing]) else AC_MSG_ERROR([unsupported --with-sandbox]) fi # Cheap hack to ensure NEWS-OS libraries are arranged right. if test ! -z "$SONY" ; then LIBS="$LIBS -liberty"; fi # Check for long long datatypes AC_CHECK_TYPES([long long, unsigned long long, long double]) # Check datatype sizes AC_CHECK_SIZEOF([short int], [2]) AC_CHECK_SIZEOF([int], [4]) AC_CHECK_SIZEOF([long int], [4]) AC_CHECK_SIZEOF([long long int], [8]) # Sanity check long long for some platforms (AIX) if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then ac_cv_sizeof_long_long_int=0 fi # compute LLONG_MIN and LLONG_MAX if we don't know them. if test -z "$have_llong_max"; then AC_MSG_CHECKING([for max value of long long]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include /* Why is this so damn hard? */ #ifdef __GNUC__ # undef __GNUC__ #endif #define __USE_ISOC99 #include #define DATA "conftest.llminmax" #define my_abs(a) ((a) < 0 ? ((a) * -1) : (a)) /* * printf in libc on some platforms (eg old Tru64) does not understand %lld so * we do this the hard way. */ static int fprint_ll(FILE *f, long long n) { unsigned int i; int l[sizeof(long long) * 8]; if (n < 0) if (fprintf(f, "-") < 0) return -1; for (i = 0; n != 0; i++) { l[i] = my_abs(n % 10); n /= 10; } do { if (fprintf(f, "%d", l[--i]) < 0) return -1; } while (i != 0); if (fprintf(f, " ") < 0) return -1; return 0; } ]], [[ FILE *f; long long i, llmin, llmax = 0; if((f = fopen(DATA,"w")) == NULL) exit(1); #if defined(LLONG_MIN) && defined(LLONG_MAX) fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n"); llmin = LLONG_MIN; llmax = LLONG_MAX; #else fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n"); /* This will work on one's complement and two's complement */ for (i = 1; i > llmax; i <<= 1, i++) llmax = i; llmin = llmax + 1LL; /* wrap */ #endif /* Sanity check */ if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax || llmax - 1 > llmax || llmin == llmax || llmin == 0 || llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) { fprintf(f, "unknown unknown\n"); exit(2); } if (fprint_ll(f, llmin) < 0) exit(3); if (fprint_ll(f, llmax) < 0) exit(4); if (fclose(f) < 0) exit(5); exit(0); ]])], [ llong_min=`$AWK '{print $1}' conftest.llminmax` llong_max=`$AWK '{print $2}' conftest.llminmax` AC_MSG_RESULT([$llong_max]) AC_DEFINE_UNQUOTED([LLONG_MAX], [${llong_max}LL], [max value of long long calculated by configure]) AC_MSG_CHECKING([for min value of long long]) AC_MSG_RESULT([$llong_min]) AC_DEFINE_UNQUOTED([LLONG_MIN], [${llong_min}LL], [min value of long long calculated by configure]) ], [ AC_MSG_RESULT([not found]) ], [ AC_MSG_WARN([cross compiling: not checking]) ] ) fi # More checks for data types AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int a; a = 1;]])], [ ac_cv_have_u_int="yes" ], [ ac_cv_have_u_int="no" ]) ]) if test "x$ac_cv_have_u_int" = "xyes" ; then AC_DEFINE([HAVE_U_INT], [1], [define if you have u_int data type]) have_u_int=1 fi AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])], [ ac_cv_have_intxx_t="yes" ], [ ac_cv_have_intxx_t="no" ]) ]) if test "x$ac_cv_have_intxx_t" = "xyes" ; then AC_DEFINE([HAVE_INTXX_T], [1], [define if you have intxx_t data type]) have_intxx_t=1 fi if (test -z "$have_intxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then AC_MSG_CHECKING([for intXX_t types in stdint.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])], [ AC_DEFINE([HAVE_INTXX_T]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) fi AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #ifdef HAVE_STDINT_H # include #endif #include #ifdef HAVE_SYS_BITYPES_H # include #endif ]], [[ int64_t a; a = 1; ]])], [ ac_cv_have_int64_t="yes" ], [ ac_cv_have_int64_t="no" ]) ]) if test "x$ac_cv_have_int64_t" = "xyes" ; then AC_DEFINE([HAVE_INT64_T], [1], [define if you have int64_t data type]) fi AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])], [ ac_cv_have_u_intxx_t="yes" ], [ ac_cv_have_u_intxx_t="no" ]) ]) if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then AC_DEFINE([HAVE_U_INTXX_T], [1], [define if you have u_intxx_t data type]) have_u_intxx_t=1 fi if test -z "$have_u_intxx_t" ; then AC_MSG_CHECKING([for u_intXX_t types in sys/socket.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])], [ AC_DEFINE([HAVE_U_INTXX_T]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) fi AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int64_t a; a = 1;]])], [ ac_cv_have_u_int64_t="yes" ], [ ac_cv_have_u_int64_t="no" ]) ]) if test "x$ac_cv_have_u_int64_t" = "xyes" ; then AC_DEFINE([HAVE_U_INT64_T], [1], [define if you have u_int64_t data type]) have_u_int64_t=1 fi if (test -z "$have_u_int64_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_int64_t a; a = 1]])], [ AC_DEFINE([HAVE_U_INT64_T]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) fi if test -z "$have_u_intxx_t" ; then AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ]])], [ ac_cv_have_uintxx_t="yes" ], [ ac_cv_have_uintxx_t="no" ]) ]) if test "x$ac_cv_have_uintxx_t" = "xyes" ; then AC_DEFINE([HAVE_UINTXX_T], [1], [define if you have uintxx_t data type]) fi fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then AC_MSG_CHECKING([for uintXX_t types in stdint.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])], [ AC_DEFINE([HAVE_UINTXX_T]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_inttypes_h" = "xyes") then AC_MSG_CHECKING([for uintXX_t types in inttypes.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])], [ AC_DEFINE([HAVE_UINTXX_T]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) fi if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ int8_t a; int16_t b; int32_t c; u_int8_t e; u_int16_t f; u_int32_t g; a = b = c = e = f = g = 1; ]])], [ AC_DEFINE([HAVE_U_INTXX_T]) AC_DEFINE([HAVE_INTXX_T]) AC_MSG_RESULT([yes]) ], [AC_MSG_RESULT([no]) ]) fi AC_CACHE_CHECK([for u_char], ac_cv_have_u_char, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ u_char foo; foo = 125; ]])], [ ac_cv_have_u_char="yes" ], [ ac_cv_have_u_char="no" ]) ]) if test "x$ac_cv_have_u_char" = "xyes" ; then AC_DEFINE([HAVE_U_CHAR], [1], [define if you have u_char data type]) fi AC_CHECK_TYPES([intmax_t, uintmax_t], , , [ #include #include ]) TYPE_SOCKLEN_T AC_CHECK_TYPES([sig_atomic_t], , , [#include ]) AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t], , , [ #include #ifdef HAVE_SYS_BITYPES_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif ]) AC_CHECK_TYPES([in_addr_t, in_port_t], , , [#include #include ]) AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ size_t foo; foo = 1235; ]])], [ ac_cv_have_size_t="yes" ], [ ac_cv_have_size_t="no" ]) ]) if test "x$ac_cv_have_size_t" = "xyes" ; then AC_DEFINE([HAVE_SIZE_T], [1], [define if you have size_t data type]) fi AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ ssize_t foo; foo = 1235; ]])], [ ac_cv_have_ssize_t="yes" ], [ ac_cv_have_ssize_t="no" ]) ]) if test "x$ac_cv_have_ssize_t" = "xyes" ; then AC_DEFINE([HAVE_SSIZE_T], [1], [define if you have ssize_t data type]) fi AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ clock_t foo; foo = 1235; ]])], [ ac_cv_have_clock_t="yes" ], [ ac_cv_have_clock_t="no" ]) ]) if test "x$ac_cv_have_clock_t" = "xyes" ; then AC_DEFINE([HAVE_CLOCK_T], [1], [define if you have clock_t data type]) fi AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ sa_family_t foo; foo = 1235; ]])], [ ac_cv_have_sa_family_t="yes" ], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ sa_family_t foo; foo = 1235; ]])], [ ac_cv_have_sa_family_t="yes" ], [ ac_cv_have_sa_family_t="no" ] ) ]) ]) if test "x$ac_cv_have_sa_family_t" = "xyes" ; then AC_DEFINE([HAVE_SA_FAMILY_T], [1], [define if you have sa_family_t data type]) fi AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ pid_t foo; foo = 1235; ]])], [ ac_cv_have_pid_t="yes" ], [ ac_cv_have_pid_t="no" ]) ]) if test "x$ac_cv_have_pid_t" = "xyes" ; then AC_DEFINE([HAVE_PID_T], [1], [define if you have pid_t data type]) fi AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ mode_t foo; foo = 1235; ]])], [ ac_cv_have_mode_t="yes" ], [ ac_cv_have_mode_t="no" ]) ]) if test "x$ac_cv_have_mode_t" = "xyes" ; then AC_DEFINE([HAVE_MODE_T], [1], [define if you have mode_t data type]) fi AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct sockaddr_storage s; ]])], [ ac_cv_have_struct_sockaddr_storage="yes" ], [ ac_cv_have_struct_sockaddr_storage="no" ]) ]) if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then AC_DEFINE([HAVE_STRUCT_SOCKADDR_STORAGE], [1], [define if you have struct sockaddr_storage data type]) fi AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct sockaddr_in6 s; s.sin6_family = 0; ]])], [ ac_cv_have_struct_sockaddr_in6="yes" ], [ ac_cv_have_struct_sockaddr_in6="no" ]) ]) if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then AC_DEFINE([HAVE_STRUCT_SOCKADDR_IN6], [1], [define if you have struct sockaddr_in6 data type]) fi AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct in6_addr s; s.s6_addr[0] = 0; ]])], [ ac_cv_have_struct_in6_addr="yes" ], [ ac_cv_have_struct_in6_addr="no" ]) ]) if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then AC_DEFINE([HAVE_STRUCT_IN6_ADDR], [1], [define if you have struct in6_addr data type]) dnl Now check for sin6_scope_id AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id], , , [ #ifdef HAVE_SYS_TYPES_H #include #endif #include ]) fi AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ struct addrinfo s; s.ai_flags = AI_PASSIVE; ]])], [ ac_cv_have_struct_addrinfo="yes" ], [ ac_cv_have_struct_addrinfo="no" ]) ]) if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then AC_DEFINE([HAVE_STRUCT_ADDRINFO], [1], [define if you have struct addrinfo data type]) fi AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ struct timeval tv; tv.tv_sec = 1;]])], [ ac_cv_have_struct_timeval="yes" ], [ ac_cv_have_struct_timeval="no" ]) ]) if test "x$ac_cv_have_struct_timeval" = "xyes" ; then AC_DEFINE([HAVE_STRUCT_TIMEVAL], [1], [define if you have struct timeval]) have_struct_timeval=1 fi AC_CHECK_TYPES([struct timespec]) # We need int64_t or else certian parts of the compile will fail. if test "x$ac_cv_have_int64_t" = "xno" && \ test "x$ac_cv_sizeof_long_int" != "x8" && \ test "x$ac_cv_sizeof_long_long_int" = "x0" ; then echo "OpenSSH requires int64_t support. Contact your vendor or install" echo "an alternative compiler (I.E., GCC) before continuing." echo "" exit 1; else dnl test snprintf (broken on SCO w/gcc) AC_RUN_IFELSE( [AC_LANG_SOURCE([[ #include #include #ifdef HAVE_SNPRINTF main() { char buf[50]; char expected_out[50]; int mazsize = 50 ; #if (SIZEOF_LONG_INT == 8) long int num = 0x7fffffffffffffff; #else long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); snprintf(buf, mazsize, "%lld", num); if(strcmp(buf, expected_out) != 0) exit(1); exit(0); } #else main() { exit(0); } #endif ]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ], AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ) fi dnl Checks for structure members OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmp.h], [HAVE_HOST_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmpx.h], [HAVE_HOST_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([syslen], [utmpx.h], [HAVE_SYSLEN_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_pid], [utmp.h], [HAVE_PID_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmp.h], [HAVE_TYPE_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmpx.h], [HAVE_TYPE_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmp.h], [HAVE_TV_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmp.h], [HAVE_ID_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmpx.h], [HAVE_ID_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmp.h], [HAVE_ADDR_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmpx.h], [HAVE_ADDR_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmp.h], [HAVE_ADDR_V6_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmpx.h], [HAVE_ADDR_V6_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_exit], [utmp.h], [HAVE_EXIT_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmp.h], [HAVE_TIME_IN_UTMP]) OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmpx.h], [HAVE_TIME_IN_UTMPX]) OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX]) AC_CHECK_MEMBERS([struct stat.st_blksize]) AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class, struct passwd.pw_change, struct passwd.pw_expire], [], [], [[ #include #include ]]) AC_CHECK_MEMBER([struct __res_state.retrans], [], [AC_DEFINE([__res_state], [state], [Define if we don't have struct __res_state in resolv.h])], [[ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include ]]) AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], ac_cv_have_ss_family_in_struct_ss, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct sockaddr_storage s; s.ss_family = 1; ]])], [ ac_cv_have_ss_family_in_struct_ss="yes" ], [ ac_cv_have_ss_family_in_struct_ss="no" ]) ]) if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then AC_DEFINE([HAVE_SS_FAMILY_IN_SS], [1], [Fields in struct sockaddr_storage]) fi AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], ac_cv_have___ss_family_in_struct_ss, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct sockaddr_storage s; s.__ss_family = 1; ]])], [ ac_cv_have___ss_family_in_struct_ss="yes" ], [ ac_cv_have___ss_family_in_struct_ss="no" ]) ]) if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then AC_DEFINE([HAVE___SS_FAMILY_IN_SS], [1], [Fields in struct sockaddr_storage]) fi dnl make sure we're using the real structure members and not defines AC_CACHE_CHECK([for msg_accrights field in struct msghdr], ac_cv_have_accrights_in_msghdr, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ #ifdef msg_accrights #error "msg_accrights is a macro" exit(1); #endif struct msghdr m; m.msg_accrights = 0; exit(0); ]])], [ ac_cv_have_accrights_in_msghdr="yes" ], [ ac_cv_have_accrights_in_msghdr="no" ] ) ]) if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then AC_DEFINE([HAVE_ACCRIGHTS_IN_MSGHDR], [1], [Define if your system uses access rights style file descriptor passing]) fi AC_MSG_CHECKING([if struct statvfs.f_fsid is integral type]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif ]], [[ struct statvfs s; s.f_fsid = 0; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_MSG_CHECKING([if fsid_t has member val]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ fsid_t t; t.val[0] = 0; ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([FSID_HAS_VAL], [1], [fsid_t has member val]) ], [ AC_MSG_RESULT([no]) ]) AC_MSG_CHECKING([if f_fsid has member __val]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ fsid_t t; t.__val[0] = 0; ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([FSID_HAS___VAL], [1], [fsid_t has member __val]) ], [ AC_MSG_RESULT([no]) ]) ]) AC_CACHE_CHECK([for msg_control field in struct msghdr], ac_cv_have_control_in_msghdr, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ #ifdef msg_control #error "msg_control is a macro" exit(1); #endif struct msghdr m; m.msg_control = 0; exit(0); ]])], [ ac_cv_have_control_in_msghdr="yes" ], [ ac_cv_have_control_in_msghdr="no" ] ) ]) if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then AC_DEFINE([HAVE_CONTROL_IN_MSGHDR], [1], [Define if your system uses ancillary data style file descriptor passing]) fi AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ extern char *__progname; printf("%s", __progname); ]])], [ ac_cv_libc_defines___progname="yes" ], [ ac_cv_libc_defines___progname="no" ]) ]) if test "x$ac_cv_libc_defines___progname" = "xyes" ; then AC_DEFINE([HAVE___PROGNAME], [1], [Define if libc defines __progname]) fi AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ printf("%s", __FUNCTION__); ]])], [ ac_cv_cc_implements___FUNCTION__="yes" ], [ ac_cv_cc_implements___FUNCTION__="no" ]) ]) if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then AC_DEFINE([HAVE___FUNCTION__], [1], [Define if compiler implements __FUNCTION__]) fi AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ printf("%s", __func__); ]])], [ ac_cv_cc_implements___func__="yes" ], [ ac_cv_cc_implements___func__="no" ]) ]) if test "x$ac_cv_cc_implements___func__" = "xyes" ; then AC_DEFINE([HAVE___func__], [1], [Define if compiler implements __func__]) fi AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include va_list x,y; ]], [[ va_copy(x,y); ]])], [ ac_cv_have_va_copy="yes" ], [ ac_cv_have_va_copy="no" ]) ]) if test "x$ac_cv_have_va_copy" = "xyes" ; then AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists]) fi AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include va_list x,y; ]], [[ __va_copy(x,y); ]])], [ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no" ]) ]) if test "x$ac_cv_have___va_copy" = "xyes" ; then AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists]) fi AC_CACHE_CHECK([whether getopt has optreset support], ac_cv_have_getopt_optreset, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ extern int optreset; optreset = 0; ]])], [ ac_cv_have_getopt_optreset="yes" ], [ ac_cv_have_getopt_optreset="no" ]) ]) if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then AC_DEFINE([HAVE_GETOPT_OPTRESET], [1], [Define if your getopt(3) defines and uses optreset]) fi AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);]])], [ ac_cv_libc_defines_sys_errlist="yes" ], [ ac_cv_libc_defines_sys_errlist="no" ]) ]) if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then AC_DEFINE([HAVE_SYS_ERRLIST], [1], [Define if your system defines sys_errlist[]]) fi AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ extern int sys_nerr; printf("%i", sys_nerr);]])], [ ac_cv_libc_defines_sys_nerr="yes" ], [ ac_cv_libc_defines_sys_nerr="no" ]) ]) if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then AC_DEFINE([HAVE_SYS_NERR], [1], [Define if your system defines sys_nerr]) fi # Check libraries needed by DNS fingerprint support AC_SEARCH_LIBS([getrrsetbyname], [resolv], [AC_DEFINE([HAVE_GETRRSETBYNAME], [1], [Define if getrrsetbyname() exists])], [ # Needed by our getrrsetbyname() AC_SEARCH_LIBS([res_query], [resolv]) AC_SEARCH_LIBS([dn_expand], [resolv]) AC_MSG_CHECKING([if res_query will link]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include #include #include ]], [[ res_query (0, 0, 0, 0, 0); ]])], AC_MSG_RESULT([yes]), [AC_MSG_RESULT([no]) saved_LIBS="$LIBS" LIBS="$LIBS -lresolv" AC_MSG_CHECKING([for res_query in -lresolv]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include #include #include ]], [[ res_query (0, 0, 0, 0, 0); ]])], [AC_MSG_RESULT([yes])], [LIBS="$saved_LIBS" AC_MSG_RESULT([no])]) ]) AC_CHECK_FUNCS([_getshort _getlong]) AC_CHECK_DECLS([_getshort, _getlong], , , [#include #include ]) AC_CHECK_MEMBER([HEADER.ad], [AC_DEFINE([HAVE_HEADER_AD], [1], [Define if HEADER.ad exists in arpa/nameser.h])], , [#include ]) ]) AC_MSG_CHECKING([if struct __res_state _res is an extern]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include extern struct __res_state _res; ]], [[ struct __res_state *volatile p = &_res; /* force resolution of _res */ return 0; ]],)], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE__RES_EXTERN], [1], [Define if you have struct __res_state _res as an extern]) ], [ AC_MSG_RESULT([no]) ] ) # Check whether user wants SELinux support SELINUX_MSG="no" LIBSELINUX="" AC_ARG_WITH([selinux], [ --with-selinux Enable SELinux support], [ if test "x$withval" != "xno" ; then save_LIBS="$LIBS" AC_DEFINE([WITH_SELINUX], [1], [Define if you want SELinux support.]) SELINUX_MSG="yes" AC_CHECK_HEADER([selinux/selinux.h], , AC_MSG_ERROR([SELinux support requires selinux.h header])) AC_CHECK_LIB([selinux], [setexeccon], [ LIBSELINUX="-lselinux" LIBS="$LIBS -lselinux" ], AC_MSG_ERROR([SELinux support requires libselinux library])) SSHLIBS="$SSHLIBS $LIBSELINUX" SSHDLIBS="$SSHDLIBS $LIBSELINUX" AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) LIBS="$save_LIBS" fi ] ) AC_SUBST([SSHLIBS]) AC_SUBST([SSHDLIBS]) # Check whether user wants Kerberos 5 support KRB5_MSG="no" AC_ARG_WITH([kerberos5], [ --with-kerberos5=PATH Enable Kerberos 5 support], [ if test "x$withval" != "xno" ; then if test "x$withval" = "xyes" ; then KRB5ROOT="/usr/local" else KRB5ROOT=${withval} fi AC_DEFINE([KRB5], [1], [Define if you want Kerberos 5 support]) KRB5_MSG="yes" AC_PATH_PROG([KRB5CONF], [krb5-config], [$KRB5ROOT/bin/krb5-config], [$KRB5ROOT/bin:$PATH]) if test -x $KRB5CONF ; then K5CFLAGS="`$KRB5CONF --cflags`" K5LIBS="`$KRB5CONF --libs`" CPPFLAGS="$CPPFLAGS $K5CFLAGS" AC_MSG_CHECKING([for gssapi support]) if $KRB5CONF | grep gssapi >/dev/null ; then AC_MSG_RESULT([yes]) AC_DEFINE([GSSAPI], [1], [Define this if you want GSSAPI support in the version 2 protocol]) GSSCFLAGS="`$KRB5CONF --cflags gssapi`" GSSLIBS="`$KRB5CONF --libs gssapi`" CPPFLAGS="$CPPFLAGS $GSSCFLAGS" else AC_MSG_RESULT([no]) fi AC_MSG_CHECKING([whether we are using Heimdal]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *tmp = heimdal_version; ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([HEIMDAL], [1], [Define this if you are using the Heimdal version of Kerberos V5]) ], [AC_MSG_RESULT([no]) ]) else CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include" LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib" AC_MSG_CHECKING([whether we are using Heimdal]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *tmp = heimdal_version; ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([HEIMDAL]) K5LIBS="-lkrb5" K5LIBS="$K5LIBS -lcom_err -lasn1" AC_CHECK_LIB([roken], [net_write], [K5LIBS="$K5LIBS -lroken"]) AC_CHECK_LIB([des], [des_cbc_encrypt], [K5LIBS="$K5LIBS -ldes"]) ], [ AC_MSG_RESULT([no]) K5LIBS="-lkrb5 -lk5crypto -lcom_err" ]) AC_SEARCH_LIBS([dn_expand], [resolv]) AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context], [ AC_DEFINE([GSSAPI]) GSSLIBS="-lgssapi_krb5" ], [ AC_CHECK_LIB([gssapi], [gss_init_sec_context], [ AC_DEFINE([GSSAPI]) GSSLIBS="-lgssapi" ], [ AC_CHECK_LIB([gss], [gss_init_sec_context], [ AC_DEFINE([GSSAPI]) GSSLIBS="-lgss" ], AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail])) ]) ]) AC_CHECK_HEADER([gssapi.h], , [ unset ac_cv_header_gssapi_h CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" AC_CHECK_HEADERS([gssapi.h], , AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail]) ) ] ) oldCPP="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" fi if test ! -z "$blibpath" ; then blibpath="$blibpath:${KRB5ROOT}/lib" fi AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h]) AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h]) AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h]) AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1], [Define this if you want to use libkafs' AFS support])]) AC_CHECK_DECLS([GSS_C_NT_HOSTBASED_SERVICE], [], [], [[ #ifdef HAVE_GSSAPI_H # include #elif defined(HAVE_GSSAPI_GSSAPI_H) # include #endif #ifdef HAVE_GSSAPI_GENERIC_H # include #elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) # include #endif ]]) saved_LIBS="$LIBS" LIBS="$LIBS $K5LIBS" AC_CHECK_FUNCS([krb5_cc_new_unique krb5_get_error_message krb5_free_error_message]) LIBS="$saved_LIBS" fi ] ) AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) # Looking for programs, paths and files PRIVSEP_PATH=/var/empty AC_ARG_WITH([privsep-path], [ --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then PRIVSEP_PATH=$withval fi ] ) AC_SUBST([PRIVSEP_PATH]) AC_ARG_WITH([xauth], [ --with-xauth=PATH Specify path to xauth program ], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then xauth_path=$withval fi ], [ TestPath="$PATH" TestPath="${TestPath}${PATH_SEPARATOR}/usr/X/bin" TestPath="${TestPath}${PATH_SEPARATOR}/usr/bin/X11" TestPath="${TestPath}${PATH_SEPARATOR}/usr/X11R6/bin" TestPath="${TestPath}${PATH_SEPARATOR}/usr/openwin/bin" AC_PATH_PROG([xauth_path], [xauth], , [$TestPath]) if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then xauth_path="/usr/openwin/bin/xauth" fi ] ) STRIP_OPT=-s AC_ARG_ENABLE([strip], [ --disable-strip Disable calling strip(1) on install], [ if test "x$enableval" = "xno" ; then STRIP_OPT= fi ] ) AC_SUBST([STRIP_OPT]) if test -z "$xauth_path" ; then XAUTH_PATH="undefined" AC_SUBST([XAUTH_PATH]) else AC_DEFINE_UNQUOTED([XAUTH_PATH], ["$xauth_path"], [Define if xauth is found in your path]) XAUTH_PATH=$xauth_path AC_SUBST([XAUTH_PATH]) fi dnl # --with-maildir=/path/to/mail gets top priority. dnl # if maildir is set in the platform case statement above we use that. dnl # Otherwise we run a program to get the dir from system headers. dnl # We first look for _PATH_MAILDIR then MAILDIR then _PATH_MAIL dnl # If we find _PATH_MAILDIR we do nothing because that is what dnl # session.c expects anyway. Otherwise we set to the value found dnl # stripping any trailing slash. If for some strage reason our program dnl # does not find what it needs, we default to /var/spool/mail. # Check for mail directory AC_ARG_WITH([maildir], [ --with-maildir=/path/to/mail Specify your system mail directory], [ if test "X$withval" != X && test "x$withval" != xno && \ test "x${withval}" != xyes; then AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$withval"], [Set this to your mail directory if you do not have _PATH_MAILDIR]) fi ],[ if test "X$maildir" != "X"; then AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"]) else AC_MSG_CHECKING([Discovering system mail directory]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_PATHS_H #include #endif #ifdef HAVE_MAILLOCK_H #include #endif #define DATA "conftest.maildir" ]], [[ FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); #if defined (_PATH_MAILDIR) if ((rc = fprintf(fd ,"_PATH_MAILDIR:%s\n", _PATH_MAILDIR)) <0) exit(1); #elif defined (MAILDIR) if ((rc = fprintf(fd ,"MAILDIR:%s\n", MAILDIR)) <0) exit(1); #elif defined (_PATH_MAIL) if ((rc = fprintf(fd ,"_PATH_MAIL:%s\n", _PATH_MAIL)) <0) exit(1); #else exit (2); #endif exit(0); ]])], [ maildir_what=`awk -F: '{print $1}' conftest.maildir` maildir=`awk -F: '{print $2}' conftest.maildir \ | sed 's|/$||'` AC_MSG_RESULT([Using: $maildir from $maildir_what]) if test "x$maildir_what" != "x_PATH_MAILDIR"; then AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"]) fi ], [ if test "X$ac_status" = "X2";then # our test program didn't find it. Default to /var/spool/mail AC_MSG_RESULT([Using: default value of /var/spool/mail]) AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["/var/spool/mail"]) else AC_MSG_RESULT([*** not found ***]) fi ], [ AC_MSG_WARN([cross compiling: use --with-maildir=/path/to/mail]) ] ) fi ] ) # maildir if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test]) disable_ptmx_check=yes fi if test -z "$no_dev_ptmx" ; then if test "x$disable_ptmx_check" != "xyes" ; then AC_CHECK_FILE(["/dev/ptmx"], [ AC_DEFINE_UNQUOTED([HAVE_DEV_PTMX], [1], [Define if you have /dev/ptmx]) have_dev_ptmx=1 ] ) fi fi if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then AC_CHECK_FILE(["/dev/ptc"], [ AC_DEFINE_UNQUOTED([HAVE_DEV_PTS_AND_PTC], [1], [Define if you have /dev/ptc]) have_dev_ptc=1 ] ) else AC_MSG_WARN([cross compiling: Disabling /dev/ptc test]) fi # Options from here on. Some of these are preset by platform above AC_ARG_WITH([mantype], [ --with-mantype=man|cat|doc Set man page type], [ case "$withval" in man|cat|doc) MANTYPE=$withval ;; *) AC_MSG_ERROR([invalid man type: $withval]) ;; esac ] ) if test -z "$MANTYPE"; then TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb" AC_PATH_PROGS([NROFF], [nroff awf], [/bin/false], [$TestPath]) if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then MANTYPE=doc elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then MANTYPE=man else MANTYPE=cat fi fi AC_SUBST([MANTYPE]) if test "$MANTYPE" = "doc"; then mansubdir=man; else mansubdir=$MANTYPE; fi AC_SUBST([mansubdir]) # Check whether to enable MD5 passwords MD5_MSG="no" AC_ARG_WITH([md5-passwords], [ --with-md5-passwords Enable use of MD5 passwords], [ if test "x$withval" != "xno" ; then AC_DEFINE([HAVE_MD5_PASSWORDS], [1], [Define if you want to allow MD5 passwords]) MD5_MSG="yes" fi ] ) # Whether to disable shadow password support AC_ARG_WITH([shadow], [ --without-shadow Disable shadow password support], [ if test "x$withval" = "xno" ; then AC_DEFINE([DISABLE_SHADOW]) disable_shadow=yes fi ] ) if test -z "$disable_shadow" ; then AC_MSG_CHECKING([if the systems has expire shadow information]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include struct spwd sp; ]], [[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ]])], [ sp_expire_available=yes ], [ ]) if test "x$sp_expire_available" = "xyes" ; then AC_MSG_RESULT([yes]) AC_DEFINE([HAS_SHADOW_EXPIRE], [1], [Define if you want to use shadow password expire field]) else AC_MSG_RESULT([no]) fi fi # Use ip address instead of hostname in $DISPLAY if test ! -z "$IPADDR_IN_DISPLAY" ; then DISPLAY_HACK_MSG="yes" AC_DEFINE([IPADDR_IN_DISPLAY], [1], [Define if you need to use IP address instead of hostname in $DISPLAY]) else DISPLAY_HACK_MSG="no" AC_ARG_WITH([ipaddr-display], [ --with-ipaddr-display Use ip address instead of hostname in $DISPLAY], [ if test "x$withval" != "xno" ; then AC_DEFINE([IPADDR_IN_DISPLAY]) DISPLAY_HACK_MSG="yes" fi ] ) fi # check for /etc/default/login and use it if present. AC_ARG_ENABLE([etc-default-login], [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]], [ if test "x$enableval" = "xno"; then AC_MSG_NOTICE([/etc/default/login handling disabled]) etc_default_login=no else etc_default_login=yes fi ], [ if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then AC_MSG_WARN([cross compiling: not checking /etc/default/login]) etc_default_login=no else etc_default_login=yes fi ] ) if test "x$etc_default_login" != "xno"; then AC_CHECK_FILE(["/etc/default/login"], [ external_path_file=/etc/default/login ]) if test "x$external_path_file" = "x/etc/default/login"; then AC_DEFINE([HAVE_ETC_DEFAULT_LOGIN], [1], [Define if your system has /etc/default/login]) fi fi dnl BSD systems use /etc/login.conf so --with-default-path= has no effect if test $ac_cv_func_login_getcapbool = "yes" && \ test $ac_cv_header_login_cap_h = "yes" ; then external_path_file=/etc/login.conf fi # Whether to mess with the default path SERVER_PATH_MSG="(default)" AC_ARG_WITH([default-path], [ --with-default-path= Specify default $PATH environment for server], [ if test "x$external_path_file" = "x/etc/login.conf" ; then AC_MSG_WARN([ --with-default-path=PATH has no effect on this system. Edit /etc/login.conf instead.]) elif test "x$withval" != "xno" ; then if test ! -z "$external_path_file" ; then AC_MSG_WARN([ --with-default-path=PATH will only be used if PATH is not defined in $external_path_file .]) fi user_path="$withval" SERVER_PATH_MSG="$withval" fi ], [ if test "x$external_path_file" = "x/etc/login.conf" ; then AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf]) else if test ! -z "$external_path_file" ; then AC_MSG_WARN([ If PATH is defined in $external_path_file, ensure the path to scp is included, otherwise scp will not work.]) fi AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ /* find out what STDPATH is */ #include #ifdef HAVE_PATHS_H # include #endif #ifndef _PATH_STDPATH # ifdef _PATH_USERPATH /* Irix */ # define _PATH_STDPATH _PATH_USERPATH # else # define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" # endif #endif #include #include #include #define DATA "conftest.stdpath" ]], [[ FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0) exit(1); exit(0); ]])], [ user_path=`cat conftest.stdpath` ], [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ], [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ] ) # make sure $bindir is in USER_PATH so scp will work t_bindir="${bindir}" while echo "${t_bindir}" | egrep '\$\{|NONE/' >/dev/null 2>&1; do t_bindir=`eval echo ${t_bindir}` case $t_bindir in NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;; esac case $t_bindir in NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;; esac done echo $user_path | grep ":$t_bindir" > /dev/null 2>&1 if test $? -ne 0 ; then echo $user_path | grep "^$t_bindir" > /dev/null 2>&1 if test $? -ne 0 ; then user_path=$user_path:$t_bindir AC_MSG_RESULT([Adding $t_bindir to USER_PATH so scp will work]) fi fi fi ] ) if test "x$external_path_file" != "x/etc/login.conf" ; then AC_DEFINE_UNQUOTED([USER_PATH], ["$user_path"], [Specify default $PATH]) AC_SUBST([user_path]) fi # Set superuser path separately to user path AC_ARG_WITH([superuser-path], [ --with-superuser-path= Specify different path for super-user], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then AC_DEFINE_UNQUOTED([SUPERUSER_PATH], ["$withval"], [Define if you want a different $PATH for the superuser]) superuser_path=$withval fi ] ) AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses]) IPV4_IN6_HACK_MSG="no" AC_ARG_WITH(4in6, [ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses], [ if test "x$withval" != "xno" ; then AC_MSG_RESULT([yes]) AC_DEFINE([IPV4_IN_IPV6], [1], [Detect IPv4 in IPv6 mapped addresses and treat as IPv4]) IPV4_IN6_HACK_MSG="yes" else AC_MSG_RESULT([no]) fi ], [ if test "x$inet6_default_4in6" = "xyes"; then AC_MSG_RESULT([yes (default)]) AC_DEFINE([IPV4_IN_IPV6]) IPV4_IN6_HACK_MSG="yes" else AC_MSG_RESULT([no (default)]) fi ] ) # Whether to enable BSD auth support BSD_AUTH_MSG=no AC_ARG_WITH([bsd-auth], [ --with-bsd-auth Enable BSD auth support], [ if test "x$withval" != "xno" ; then AC_DEFINE([BSD_AUTH], [1], [Define if you have BSD auth support]) BSD_AUTH_MSG=yes fi ] ) # Where to place sshd.pid piddir=/var/run # make sure the directory exists if test ! -d $piddir ; then piddir=`eval echo ${sysconfdir}` case $piddir in NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;; esac fi AC_ARG_WITH([pid-dir], [ --with-pid-dir=PATH Specify location of ssh.pid file], [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then piddir=$withval if test ! -d $piddir ; then AC_MSG_WARN([** no $piddir directory on this system **]) fi fi ] ) AC_DEFINE_UNQUOTED([_PATH_SSH_PIDDIR], ["$piddir"], [Specify location of ssh.pid]) AC_SUBST([piddir]) dnl allow user to disable some login recording features AC_ARG_ENABLE([lastlog], [ --disable-lastlog disable use of lastlog even if detected [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_LASTLOG]) fi ] ) AC_ARG_ENABLE([utmp], [ --disable-utmp disable use of utmp even if detected [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_UTMP]) fi ] ) AC_ARG_ENABLE([utmpx], [ --disable-utmpx disable use of utmpx even if detected [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_UTMPX], [1], [Define if you don't want to use utmpx]) fi ] ) AC_ARG_ENABLE([wtmp], [ --disable-wtmp disable use of wtmp even if detected [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_WTMP]) fi ] ) AC_ARG_ENABLE([wtmpx], [ --disable-wtmpx disable use of wtmpx even if detected [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_WTMPX], [1], [Define if you don't want to use wtmpx]) fi ] ) AC_ARG_ENABLE([libutil], [ --disable-libutil disable use of libutil (login() etc.) [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_LOGIN]) fi ] ) AC_ARG_ENABLE([pututline], [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_PUTUTLINE], [1], [Define if you don't want to use pututline() etc. to write [uw]tmp]) fi ] ) AC_ARG_ENABLE([pututxline], [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], [ if test "x$enableval" = "xno" ; then AC_DEFINE([DISABLE_PUTUTXLINE], [1], [Define if you don't want to use pututxline() etc. to write [uw]tmpx]) fi ] ) AC_ARG_WITH([lastlog], [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], [ if test "x$withval" = "xno" ; then AC_DEFINE([DISABLE_LASTLOG]) elif test -n "$withval" && test "x${withval}" != "xyes"; then conf_lastlog_location=$withval fi ] ) dnl lastlog, [uw]tmpx? detection dnl NOTE: set the paths in the platform section to avoid the dnl need for command-line parameters dnl lastlog and [uw]tmp are subject to a file search if all else fails dnl lastlog detection dnl NOTE: the code itself will detect if lastlog is a directory AC_MSG_CHECKING([if your system defines LASTLOG_FILE]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_LASTLOG_H # include #endif #ifdef HAVE_PATHS_H # include #endif #ifdef HAVE_LOGIN_H # include #endif ]], [[ char *lastlog = LASTLOG_FILE; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_MSG_CHECKING([if your system defines _PATH_LASTLOG]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_LASTLOG_H # include #endif #ifdef HAVE_PATHS_H # include #endif ]], [[ char *lastlog = _PATH_LASTLOG; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) system_lastlog_path=no ]) ]) if test -z "$conf_lastlog_location"; then if test x"$system_lastlog_path" = x"no" ; then for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do if (test -d "$f" || test -f "$f") ; then conf_lastlog_location=$f fi done if test -z "$conf_lastlog_location"; then AC_MSG_WARN([** Cannot find lastlog **]) dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx fi fi fi if test -n "$conf_lastlog_location"; then AC_DEFINE_UNQUOTED([CONF_LASTLOG_FILE], ["$conf_lastlog_location"], [Define if you want to specify the path to your lastlog file]) fi dnl utmp detection AC_MSG_CHECKING([if your system defines UTMP_FILE]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_PATHS_H # include #endif ]], [[ char *utmp = UTMP_FILE; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) system_utmp_path=no ]) if test -z "$conf_utmp_location"; then if test x"$system_utmp_path" = x"no" ; then for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do if test -f $f ; then conf_utmp_location=$f fi done if test -z "$conf_utmp_location"; then AC_DEFINE([DISABLE_UTMP]) fi fi fi if test -n "$conf_utmp_location"; then AC_DEFINE_UNQUOTED([CONF_UTMP_FILE], ["$conf_utmp_location"], [Define if you want to specify the path to your utmp file]) fi dnl wtmp detection AC_MSG_CHECKING([if your system defines WTMP_FILE]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_PATHS_H # include #endif ]], [[ char *wtmp = WTMP_FILE; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) system_wtmp_path=no ]) if test -z "$conf_wtmp_location"; then if test x"$system_wtmp_path" = x"no" ; then for f in /usr/adm/wtmp /var/log/wtmp; do if test -f $f ; then conf_wtmp_location=$f fi done if test -z "$conf_wtmp_location"; then AC_DEFINE([DISABLE_WTMP]) fi fi fi if test -n "$conf_wtmp_location"; then AC_DEFINE_UNQUOTED([CONF_WTMP_FILE], ["$conf_wtmp_location"], [Define if you want to specify the path to your wtmp file]) fi dnl wtmpx detection AC_MSG_CHECKING([if your system defines WTMPX_FILE]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_PATHS_H # include #endif ]], [[ char *wtmpx = WTMPX_FILE; ]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) system_wtmpx_path=no ]) if test -z "$conf_wtmpx_location"; then if test x"$system_wtmpx_path" = x"no" ; then AC_DEFINE([DISABLE_WTMPX]) fi else AC_DEFINE_UNQUOTED([CONF_WTMPX_FILE], ["$conf_wtmpx_location"], [Define if you want to specify the path to your wtmpx file]) fi if test ! -z "$blibpath" ; then LDFLAGS="$LDFLAGS $blibflags$blibpath" AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile]) fi AC_CHECK_MEMBER([struct lastlog.ll_line], [], [ if test x$SKIP_DISABLE_LASTLOG_DEFINE != "xyes" ; then AC_DEFINE([DISABLE_LASTLOG]) fi ], [ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif ]) AC_CHECK_MEMBER([struct utmp.ut_line], [], [ AC_DEFINE([DISABLE_UTMP]) AC_DEFINE([DISABLE_WTMP]) ], [ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif ]) dnl Adding -Werror to CFLAGS early prevents configure tests from running. dnl Add now. CFLAGS="$CFLAGS $werror_flags" if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then TEST_SSH_IPV6=no else TEST_SSH_IPV6=yes fi AC_CHECK_DECL([BROKEN_GETADDRINFO], [TEST_SSH_IPV6=no]) AC_SUBST([TEST_SSH_IPV6], [$TEST_SSH_IPV6]) AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS]) AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms]) AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ openbsd-compat/Makefile openbsd-compat/regress/Makefile \ survey.sh]) AC_OUTPUT # Print summary of options # Someone please show me a better way :) A=`eval echo ${prefix}` ; A=`eval echo ${A}` B=`eval echo ${bindir}` ; B=`eval echo ${B}` C=`eval echo ${sbindir}` ; C=`eval echo ${C}` D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}` F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` G=`eval echo ${piddir}` ; G=`eval echo ${G}` H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}` I=`eval echo ${user_path}` ; I=`eval echo ${I}` J=`eval echo ${superuser_path}` ; J=`eval echo ${J}` echo "" echo "OpenSSH has been configured with the following options:" echo " User binaries: $B" echo " System binaries: $C" echo " Configuration files: $D" echo " Askpass program: $E" echo " Manual pages: $F" echo " PID file: $G" echo " Privilege separation chroot path: $H" if test "x$external_path_file" = "x/etc/login.conf" ; then echo " At runtime, sshd will use the path defined in $external_path_file" echo " Make sure the path to scp is present, otherwise scp will not work" else echo " sshd default user PATH: $I" if test ! -z "$external_path_file"; then echo " (If PATH is set in $external_path_file it will be used instead. If" echo " used, ensure the path to scp is present, otherwise scp will not work.)" fi fi if test ! -z "$superuser_path" ; then echo " sshd superuser user PATH: $J" fi echo " Manpage format: $MANTYPE" echo " PAM support: $PAM_MSG" echo " OSF SIA support: $SIA_MSG" echo " KerberosV support: $KRB5_MSG" echo " SELinux support: $SELINUX_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" echo " Solaris privilege support: $SPP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo "" echo " Host: ${host}" echo " Compiler: ${CC}" echo " Compiler flags: ${CFLAGS}" echo "Preprocessor flags: ${CPPFLAGS}" echo " Linker flags: ${LDFLAGS}" echo " Libraries: ${LIBS}" if test ! -z "${SSHDLIBS}"; then echo " +for sshd: ${SSHDLIBS}" fi if test ! -z "${SSHLIBS}"; then echo " +for ssh: ${SSHLIBS}" fi echo "" if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then echo "SVR4 style packages are supported with \"make package\"" echo "" fi if test "x$PAM_MSG" = "xyes" ; then echo "PAM is enabled. You may need to install a PAM control file " echo "for sshd, otherwise password authentication may fail. " echo "Example PAM control files can be found in the contrib/ " echo "subdirectory" echo "" fi if test ! -z "$NO_PEERCHECK" ; then echo "WARNING: the operating system that you are using does not" echo "appear to support getpeereid(), getpeerucred() or the" echo "SO_PEERCRED getsockopt() option. These facilities are used to" echo "enforce security checks to prevent unauthorised connections to" echo "ssh-agent. Their absence increases the risk that a malicious" echo "user can connect to your agent." echo "" fi if test "$AUDIT_MODULE" = "bsm" ; then echo "WARNING: BSM audit support is currently considered EXPERIMENTAL." echo "See the Solaris section in README.platform for details." fi openssh-7.2p2/crc32.c010064400017500001750000000116611267006270000125370ustar00djmdjm/* $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; } openssh-7.2p2/crc32.h010064400017500001750000000027031267006270000125410ustar00djmdjm/* $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 openssh-7.2p2/crypto_api.h010064400017500001750000000024421267006270000137760ustar00djmdjm/* $OpenBSD: crypto_api.h,v 1.3 2013/12/17 10:36:38 markus Exp $ */ /* * Assembled from generated headers and source files by Markus Friedl. * Placed in the public domain. */ #ifndef crypto_api_h #define crypto_api_h #ifdef HAVE_STDINT_H # include #endif #include typedef int32_t crypto_int32; typedef uint32_t crypto_uint32; #define randombytes(buf, buf_len) arc4random_buf((buf), (buf_len)) #define crypto_hashblocks_sha512_STATEBYTES 64U #define crypto_hashblocks_sha512_BLOCKBYTES 128U int crypto_hashblocks_sha512(unsigned char *, const unsigned char *, unsigned long long); #define crypto_hash_sha512_BYTES 64U int crypto_hash_sha512(unsigned char *, const unsigned char *, unsigned long long); int crypto_verify_32(const unsigned char *, const unsigned char *); #define crypto_sign_ed25519_SECRETKEYBYTES 64U #define crypto_sign_ed25519_PUBLICKEYBYTES 32U #define crypto_sign_ed25519_BYTES 64U int crypto_sign_ed25519(unsigned char *, unsigned long long *, const unsigned char *, unsigned long long, const unsigned char *); int crypto_sign_ed25519_open(unsigned char *, unsigned long long *, const unsigned char *, unsigned long long, const unsigned char *); int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *); #endif /* crypto_api_h */ openssh-7.2p2/deattack.c010064400017500001750000000101471267006270000134010ustar00djmdjm/* $OpenBSD: deattack.c,v 1.32 2015/01/20 23:14:00 deraadt 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 * */ #include "includes.h" #include #include #include #include "deattack.h" #include "crc32.h" #include "sshbuf.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) PEEK_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(const u_char *S, const u_char *buf, u_int32_t len) { u_int32_t crc; const 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; } void deattack_init(struct deattack_ctx *dctx) { bzero(dctx, sizeof(*dctx)); dctx->n = HASH_MINSIZE / HASH_ENTRYSIZE; } /* Detect a crc32 compensation attack on a packet */ int detect_attack(struct deattack_ctx *dctx, const u_char *buf, u_int32_t len) { u_int32_t i, j, l, same; u_int16_t *tmp; const u_char *c, *d; if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || len % SSH_BLOCKSIZE != 0) return DEATTACK_ERROR; for (l = dctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) ; if (dctx->h == NULL) { if ((dctx->h = calloc(l, HASH_ENTRYSIZE)) == NULL) return DEATTACK_ERROR; dctx->n = l; } else { if (l > dctx->n) { if ((tmp = reallocarray(dctx->h, l, HASH_ENTRYSIZE)) == NULL) { free(dctx->h); dctx->h = NULL; return DEATTACK_ERROR; } dctx->h = tmp; dctx->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(dctx->h, HASH_UNUSEDCHAR, dctx->n * HASH_ENTRYSIZE); for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { for (i = HASH(c) & (dctx->n - 1); dctx->h[i] != HASH_UNUSED; i = (i + 1) & (dctx->n - 1)) { if (!CMP(c, buf + dctx->h[i] * SSH_BLOCKSIZE)) { if (++same > MAX_IDENTICAL) return DEATTACK_DOS_DETECTED; if (check_crc(c, buf, len)) return DEATTACK_DETECTED; else break; } } dctx->h[i] = j; } return DEATTACK_OK; } openssh-7.2p2/deattack.h010064400017500001750000000020621267006270000134030ustar00djmdjm/* $OpenBSD: deattack.h,v 1.11 2015/01/19 19:52:16 markus 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 * */ #ifndef _DEATTACK_H #define _DEATTACK_H /* Return codes */ #define DEATTACK_OK 0 #define DEATTACK_DETECTED 1 #define DEATTACK_DOS_DETECTED 2 #define DEATTACK_ERROR 3 struct deattack_ctx { u_int16_t *h; u_int32_t n; }; void deattack_init(struct deattack_ctx *); int detect_attack(struct deattack_ctx *, const u_char *, u_int32_t); #endif openssh-7.2p2/defines.h010064400017500001750000000522421267006270000132450ustar00djmdjm/* * 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.183 2014/09/02 19:33:26 djm 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 /* * Definitions for IP type of service (ip_tos) */ #include #include #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 */ /* * Definitions for DiffServ Codepoints as per RFC2474 */ #ifndef IPTOS_DSCP_AF11 # define IPTOS_DSCP_AF11 0x28 # define IPTOS_DSCP_AF12 0x30 # define IPTOS_DSCP_AF13 0x38 # define IPTOS_DSCP_AF21 0x48 # define IPTOS_DSCP_AF22 0x50 # define IPTOS_DSCP_AF23 0x58 # define IPTOS_DSCP_AF31 0x68 # define IPTOS_DSCP_AF32 0x70 # define IPTOS_DSCP_AF33 0x78 # define IPTOS_DSCP_AF41 0x88 # define IPTOS_DSCP_AF42 0x90 # define IPTOS_DSCP_AF43 0x98 # define IPTOS_DSCP_EF 0xb8 #endif /* IPTOS_DSCP_AF11 */ #ifndef IPTOS_DSCP_CS0 # define IPTOS_DSCP_CS0 0x00 # define IPTOS_DSCP_CS1 0x20 # define IPTOS_DSCP_CS2 0x40 # define IPTOS_DSCP_CS3 0x60 # define IPTOS_DSCP_CS4 0x80 # define IPTOS_DSCP_CS5 0xa0 # define IPTOS_DSCP_CS6 0xc0 # define IPTOS_DSCP_CS7 0xe0 #endif /* IPTOS_DSCP_CS0 */ #ifndef IPTOS_DSCP_EF # define IPTOS_DSCP_EF 0xb8 #endif /* IPTOS_DSCP_EF */ #ifndef PATH_MAX # ifdef _POSIX_PATH_MAX # define PATH_MAX _POSIX_PATH_MAX # endif #endif #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 HOST_NAME_MAX # include "netdb.h" /* for MAXHOSTNAMELEN */ # if defined(_POSIX_HOST_NAME_MAX) # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX # elif defined(MAXHOSTNAMELEN) # define HOST_NAME_MAX MAXHOSTNAMELEN # else # define HOST_NAME_MAX 255 # endif #endif /* HOST_NAME_MAX */ #if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0 # 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_IFSOCK # define S_IFSOCK 0 #endif /* S_IFSOCK */ #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 /* 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 typedef signed char int8_t; # 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 typedef unsigned char u_int8_t; # 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_UINTXX_T typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; typedef u_int64_t uint64_t; #endif #ifndef HAVE_INTMAX_T typedef long long intmax_t; #endif #ifndef HAVE_UINTMAX_T typedef unsigned long long uintmax_t; #endif #ifndef HAVE_U_CHAR typedef unsigned char u_char; # define HAVE_U_CHAR #endif /* HAVE_U_CHAR */ #ifndef ULLONG_MAX # define ULLONG_MAX ((unsigned long long)-1) #endif #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 SIZE_MAX #define SIZE_MAX SIZE_T_MAX #endif #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 #ifndef HAVE_IN_PORT_T typedef u_int16_t in_port_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 /* bits needed for select that may not be in the system headers */ #ifndef HAVE_FD_MASK typedef unsigned long int fd_mask; #endif #if defined(HAVE_DECL_NFDBITS) && HAVE_DECL_NFDBITS == 0 # define NFDBITS (8 * sizeof(unsigned long)) #endif #if defined(HAVE_DECL_HOWMANY) && HAVE_DECL_HOWMANY == 0 # define howmany(x,y) (((x)+((y)-1))/(y)) #endif /* Paths */ #ifndef _PATH_BSHELL # define _PATH_BSHELL "/bin/sh" #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 /* user may have set a different path */ #if defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) # undef _PATH_MAILDIR #endif /* defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) */ #ifdef MAIL_DIRECTORY # define _PATH_MAILDIR MAIL_DIRECTORY #endif #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) */ #if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__) # define __sentinel__ #endif #if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__) # define __bounded__(x, y, z) #endif #if !defined(HAVE_ATTRIBUTE__NONNULL__) && !defined(__nonnull__) # define __nonnull__(x) #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 */ #if defined(HAVE_DECL_OFFSETOF) && HAVE_DECL_OFFSETOF == 0 # 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(HAVE_GETADDRINFO) # if defined(HAVE_DECL_AI_NUMERICSERV) && HAVE_DECL_AI_NUMERICSERV == 0 # define AI_NUMERICSERV 0 # endif #endif #if defined(BROKEN_UPDWTMPX) && defined(HAVE_UPDWTMPX) # undef HAVE_UPDWTMPX #endif #if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE) # undef HAS_SHADOW_EXPIRE #endif #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \ defined(SYSLOG_R_SAFE_IN_SIGHAND) # define DO_LOG_SAFE_IN_SIGHAND #endif #if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) # define memmove(s1, s2, n) bcopy((s2), (s1), (n)) #endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */ #ifndef GETPGRP_VOID # include # define getpgrp() getpgrp(0) #endif #ifdef USE_BSM_AUDIT # define SSH_AUDIT_EVENTS # define CUSTOM_SSH_AUDIT_EVENTS #endif #ifdef USE_LINUX_AUDIT # define SSH_AUDIT_EVENTS # define CUSTOM_SSH_AUDIT_EVENTS #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 #ifdef FSID_HAS_VAL /* encode f_fsid into a 64 bit value */ #define FSID_TO_ULONG(f) \ ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \ ((f).val[1] & 0xffffffffUL)) #elif defined(FSID_HAS___VAL) #define FSID_TO_ULONG(f) \ ((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \ ((f).__val[1] & 0xffffffffUL)) #else # define FSID_TO_ULONG(f) ((f)) #endif #if defined(__Lynx__) /* * LynxOS defines these in param.h which we do not want to include since * 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... */ # if !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 #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE) # define CUSTOM_SYS_AUTH_PASSWD 1 #endif #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) # define USE_LIBIAF #endif /* HP-UX 11.11 */ #ifdef BTMP_FILE # 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 #ifndef EWOULDBLOCK # define EWOULDBLOCK EAGAIN #endif #ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ #define INET6_ADDRSTRLEN 46 #endif #ifndef SSH_IOBUFSZ # define SSH_IOBUFSZ 8192 #endif /* * Platforms that have arc4random_uniform() and not arc4random_stir() * shouldn't need the latter. */ #if defined(HAVE_ARC4RANDOM) && defined(HAVE_ARC4RANDOM_UNIFORM) && \ !defined(HAVE_ARC4RANDOM_STIR) # define arc4random_stir() #endif #ifndef HAVE_VA_COPY # ifdef HAVE___VA_COPY # define va_copy(dest, src) __va_copy(dest, src) # else # define va_copy(dest, src) (dest) = (src) # endif #endif #ifndef __predict_true # if defined(__GNUC__) && \ ((__GNUC__ > (2)) || (__GNUC__ == (2) && __GNUC_MINOR__ >= (96))) # define __predict_true(exp) __builtin_expect(((exp) != 0), 1) # define __predict_false(exp) __builtin_expect(((exp) != 0), 0) # else # define __predict_true(exp) ((exp) != 0) # define __predict_false(exp) ((exp) != 0) # endif /* gcc version */ #endif /* __predict_true */ #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \ defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \ !defined(BROKEN_GLOB) # define USE_SYSTEM_GLOB #endif #endif /* _DEFINES_H */ openssh-7.2p2/dh.c010064400017500001750000000261321267006270000122150ustar00djmdjm/* $OpenBSD: dh.c,v 1.57 2015/05/27 23:39:18 dtucker 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 /* MIN */ #include #include #include #include #include #include #include #include "dh.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "ssherr.h" static int parse_prime(int linenum, char *line, struct dhgroup *dhg) { char *cp, *arg; char *strsize, *gen, *prime; const char *errstr = NULL; long long n; dhg->p = dhg->g = 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 truncated; arg = strsep(&cp, " "); /* type */ if (cp == NULL || *arg == '\0') goto truncated; /* Ensure this is a safe prime */ n = strtonum(arg, 0, 5, &errstr); if (errstr != NULL || n != MODULI_TYPE_SAFE) { error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE); goto fail; } arg = strsep(&cp, " "); /* tests */ if (cp == NULL || *arg == '\0') goto truncated; /* Ensure prime has been tested and is not composite */ n = strtonum(arg, 0, 0x1f, &errstr); if (errstr != NULL || (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) { error("moduli:%d: invalid moduli tests flag", linenum); goto fail; } arg = strsep(&cp, " "); /* tries */ if (cp == NULL || *arg == '\0') goto truncated; n = strtonum(arg, 0, 1<<30, &errstr); if (errstr != NULL || n == 0) { error("moduli:%d: invalid primality trial count", linenum); goto fail; } strsize = strsep(&cp, " "); /* size */ if (cp == NULL || *strsize == '\0' || (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || errstr) { error("moduli:%d: invalid prime length", linenum); goto fail; } /* The whole group is one bit larger */ dhg->size++; gen = strsep(&cp, " "); /* gen */ if (cp == NULL || *gen == '\0') goto truncated; prime = strsep(&cp, " "); /* prime */ if (cp != NULL || *prime == '\0') { truncated: error("moduli:%d: truncated", linenum); goto fail; } if ((dhg->g = BN_new()) == NULL || (dhg->p = BN_new()) == NULL) { error("parse_prime: BN_new failed"); goto fail; } if (BN_hex2bn(&dhg->g, gen) == 0) { error("moduli:%d: could not parse generator value", linenum); goto fail; } if (BN_hex2bn(&dhg->p, prime) == 0) { error("moduli:%d: could not parse prime value", linenum); goto fail; } if (BN_num_bits(dhg->p) != dhg->size) { error("moduli:%d: prime has wrong size: actual %d listed %d", linenum, BN_num_bits(dhg->p), dhg->size - 1); goto fail; } if (BN_cmp(dhg->g, BN_value_one()) <= 0) { error("moduli:%d: generator is invalid", linenum); goto fail; } return 1; fail: if (dhg->g != NULL) BN_clear_free(dhg->g); if (dhg->p != NULL) BN_clear_free(dhg->p); dhg->g = dhg->p = NULL; 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_group_fallback(max)); } 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_group_fallback(max)); } linenum = 0; which = arc4random_uniform(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) { logit("WARNING: line %d disappeared in %s, giving up", which, _PATH_DH_PRIMES); return (dh_new_group_fallback(max)); } 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: negative"); 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) { error("%s: BN_new failed", __func__); return 0; } if (!BN_sub(tmp, dh->p, BN_value_one()) || BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ BN_clear_free(tmp); 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; } int dh_gen_key(DH *dh, int need) { int pbits; if (need < 0 || dh->p == NULL || (pbits = BN_num_bits(dh->p)) <= 0 || need > INT_MAX / 2 || 2 * need > pbits) return SSH_ERR_INVALID_ARGUMENT; dh->length = MIN(need * 2, pbits - 1); if (DH_generate_key(dh) == 0 || !dh_pub_is_valid(dh, dh->pub_key)) { BN_clear_free(dh->priv_key); return SSH_ERR_LIBCRYPTO_ERROR; } return 0; } DH * dh_new_group_asc(const char *gen, const char *modulus) { DH *dh; if ((dh = DH_new()) == NULL) return NULL; if (BN_hex2bn(&dh->p, modulus) == 0 || BN_hex2bn(&dh->g, gen) == 0) { DH_free(dh); return NULL; } 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) return NULL; 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)); } /* * 4k bit fallback group used by DH-GEX if moduli file cannot be read. * Source: MODP group 16 from RFC3526. */ DH * dh_new_group_fallback(int max) { static char *gen = "2", *group16 = "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" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64" "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7" "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B" "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C" "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA" "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6" "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED" "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9" "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199" "FFFFFFFF" "FFFFFFFF"; if (max < 4096) { debug3("requested max size %d, using 2k bit group 14", max); return dh_new_group14(); } debug3("using 4k bit group 16"); return (dh_new_group_asc(gen, group16)); } /* * Estimates the group order for a Diffie-Hellman group that has an * attack complexity approximately the same as O(2**bits). * Values from NIST Special Publication 800-57: Recommendation for Key * Management Part 1 (rev 3) limited by the recommended maximum value * from RFC4419 section 3. */ u_int dh_estimate(int bits) { if (bits <= 112) return 2048; if (bits <= 128) return 3072; if (bits <= 192) return 7680; return 8192; } openssh-7.2p2/dh.h010064400017500001750000000050331267006270000122170ustar00djmdjm/* $OpenBSD: dh.h,v 1.14 2015/10/16 22:32:22 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); DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); int dh_pub_is_valid(DH *, BIGNUM *); u_int dh_estimate(int); /* * Max value from RFC4419. * Miniumum increased in light of DH precomputation attacks. */ #define DH_GRP_MIN 2048 #define DH_GRP_MAX 8192 /* * Values for "type" field of moduli(5) * Specifies the internal structure of the prime modulus. */ #define MODULI_TYPE_UNKNOWN (0) #define MODULI_TYPE_UNSTRUCTURED (1) #define MODULI_TYPE_SAFE (2) #define MODULI_TYPE_SCHNORR (3) #define MODULI_TYPE_SOPHIE_GERMAIN (4) #define MODULI_TYPE_STRONG (5) /* * Values for "tests" field of moduli(5) * Specifies the methods used in checking for primality. * Usually, more than one test is used. */ #define MODULI_TESTS_UNTESTED (0x00) #define MODULI_TESTS_COMPOSITE (0x01) #define MODULI_TESTS_SIEVE (0x02) #define MODULI_TESTS_MILLER_RABIN (0x04) #define MODULI_TESTS_JACOBI (0x08) #define MODULI_TESTS_ELLIPTIC (0x10) #endif openssh-7.2p2/digest-libc.c010064400017500001750000000136211267006270000140070ustar00djmdjm/* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */ /* * Copyright (c) 2013 Damien Miller * Copyright (c) 2014 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef WITH_OPENSSL #include #include #include #include #if 0 #include #include #include #include #endif #include "ssherr.h" #include "sshbuf.h" #include "digest.h" typedef void md_init_fn(void *mdctx); typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen); typedef void md_final_fn(u_int8_t[], void *mdctx); struct ssh_digest_ctx { int alg; void *mdctx; }; struct ssh_digest { int id; const char *name; size_t block_len; size_t digest_len; size_t ctx_len; md_init_fn *md_init; md_update_fn *md_update; md_final_fn *md_final; }; /* NB. Indexed directly by algorithm number */ const struct ssh_digest digests[SSH_DIGEST_MAX] = { { SSH_DIGEST_MD5, "MD5", MD5_BLOCK_LENGTH, MD5_DIGEST_LENGTH, sizeof(MD5_CTX), (md_init_fn *) MD5Init, (md_update_fn *) MD5Update, (md_final_fn *) MD5Final }, { SSH_DIGEST_RIPEMD160, "RIPEMD160", RMD160_BLOCK_LENGTH, RMD160_DIGEST_LENGTH, sizeof(RMD160_CTX), (md_init_fn *) RMD160Init, (md_update_fn *) RMD160Update, (md_final_fn *) RMD160Final }, { SSH_DIGEST_SHA1, "SHA1", SHA1_BLOCK_LENGTH, SHA1_DIGEST_LENGTH, sizeof(SHA1_CTX), (md_init_fn *) SHA1Init, (md_update_fn *) SHA1Update, (md_final_fn *) SHA1Final }, { SSH_DIGEST_SHA256, "SHA256", SHA256_BLOCK_LENGTH, SHA256_DIGEST_LENGTH, sizeof(SHA256_CTX), (md_init_fn *) SHA256_Init, (md_update_fn *) SHA256_Update, (md_final_fn *) SHA256_Final }, { SSH_DIGEST_SHA384, "SHA384", SHA384_BLOCK_LENGTH, SHA384_DIGEST_LENGTH, sizeof(SHA384_CTX), (md_init_fn *) SHA384_Init, (md_update_fn *) SHA384_Update, (md_final_fn *) SHA384_Final }, { SSH_DIGEST_SHA512, "SHA512", SHA512_BLOCK_LENGTH, SHA512_DIGEST_LENGTH, sizeof(SHA512_CTX), (md_init_fn *) SHA512_Init, (md_update_fn *) SHA512_Update, (md_final_fn *) SHA512_Final } }; static const struct ssh_digest * ssh_digest_by_alg(int alg) { if (alg < 0 || alg >= SSH_DIGEST_MAX) return NULL; if (digests[alg].id != alg) /* sanity */ return NULL; return &(digests[alg]); } int ssh_digest_alg_by_name(const char *name) { int alg; for (alg = 0; alg < SSH_DIGEST_MAX; alg++) { if (strcasecmp(name, digests[alg].name) == 0) return digests[alg].id; } return -1; } const char * ssh_digest_alg_name(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); return digest == NULL ? NULL : digest->name; } size_t ssh_digest_bytes(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); return digest == NULL ? 0 : digest->digest_len; } size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx) { const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); return digest == NULL ? 0 : digest->block_len; } struct ssh_digest_ctx * ssh_digest_start(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); struct ssh_digest_ctx *ret; if (digest == NULL || (ret = calloc(1, sizeof(*ret))) == NULL) return NULL; if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) { free(ret); return NULL; } ret->alg = alg; digest->md_init(ret->mdctx); return ret; } int ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) { const struct ssh_digest *digest = ssh_digest_by_alg(from->alg); if (digest == NULL || from->alg != to->alg) return SSH_ERR_INVALID_ARGUMENT; memcpy(to->mdctx, from->mdctx, digest->ctx_len); return 0; } int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) { const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); if (digest == NULL) return SSH_ERR_INVALID_ARGUMENT; digest->md_update(ctx->mdctx, m, mlen); return 0; } int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b) { return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b)); } int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) { const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); if (digest == NULL) return SSH_ERR_INVALID_ARGUMENT; if (dlen > UINT_MAX) return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) /* No truncation allowed */ return SSH_ERR_INVALID_ARGUMENT; digest->md_final(d, ctx->mdctx); return 0; } void ssh_digest_free(struct ssh_digest_ctx *ctx) { const struct ssh_digest *digest; if (ctx != NULL) { digest = ssh_digest_by_alg(ctx->alg); if (digest) { explicit_bzero(ctx->mdctx, digest->ctx_len); free(ctx->mdctx); explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } } } int ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) { struct ssh_digest_ctx *ctx = ssh_digest_start(alg); if (ctx == NULL) return SSH_ERR_INVALID_ARGUMENT; if (ssh_digest_update(ctx, m, mlen) != 0 || ssh_digest_final(ctx, d, dlen) != 0) return SSH_ERR_INVALID_ARGUMENT; ssh_digest_free(ctx); return 0; } int ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } #endif /* !WITH_OPENSSL */ openssh-7.2p2/digest-openssl.c010064400017500001750000000117231267006270000145620ustar00djmdjm/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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" #ifdef WITH_OPENSSL #include #include #include #include #include #include "openbsd-compat/openssl-compat.h" #include "sshbuf.h" #include "digest.h" #include "ssherr.h" #ifndef HAVE_EVP_RIPEMD160 # define EVP_ripemd160 NULL #endif /* HAVE_EVP_RIPEMD160 */ #ifndef HAVE_EVP_SHA256 # define EVP_sha256 NULL # define EVP_sha384 NULL # define EVP_sha512 NULL #endif /* HAVE_EVP_SHA256 */ struct ssh_digest_ctx { int alg; EVP_MD_CTX mdctx; }; struct ssh_digest { int id; const char *name; size_t digest_len; const EVP_MD *(*mdfunc)(void); }; /* NB. Indexed directly by algorithm number */ const struct ssh_digest digests[] = { { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 }, { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, { -1, NULL, 0, NULL }, }; static const struct ssh_digest * ssh_digest_by_alg(int alg) { if (alg < 0 || alg >= SSH_DIGEST_MAX) return NULL; if (digests[alg].id != alg) /* sanity */ return NULL; if (digests[alg].mdfunc == NULL) return NULL; return &(digests[alg]); } int ssh_digest_alg_by_name(const char *name) { int alg; for (alg = 0; digests[alg].id != -1; alg++) { if (strcasecmp(name, digests[alg].name) == 0) return digests[alg].id; } return -1; } const char * ssh_digest_alg_name(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); return digest == NULL ? NULL : digest->name; } size_t ssh_digest_bytes(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); return digest == NULL ? 0 : digest->digest_len; } size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx) { return EVP_MD_CTX_block_size(&ctx->mdctx); } struct ssh_digest_ctx * ssh_digest_start(int alg) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); struct ssh_digest_ctx *ret; if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) return NULL; ret->alg = alg; EVP_MD_CTX_init(&ret->mdctx); if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { free(ret); return NULL; } return ret; } int ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) { if (from->alg != to->alg) return SSH_ERR_INVALID_ARGUMENT; /* we have bcopy-style order while openssl has memcpy-style */ if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) return SSH_ERR_LIBCRYPTO_ERROR; return 0; } int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) { if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) return SSH_ERR_LIBCRYPTO_ERROR; return 0; } int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b) { return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b)); } int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) { const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); u_int l = dlen; if (dlen > UINT_MAX) return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) /* No truncation allowed */ return SSH_ERR_INVALID_ARGUMENT; if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) return SSH_ERR_LIBCRYPTO_ERROR; if (l != digest->digest_len) /* sanity */ return SSH_ERR_INTERNAL_ERROR; return 0; } void ssh_digest_free(struct ssh_digest_ctx *ctx) { if (ctx != NULL) { EVP_MD_CTX_cleanup(&ctx->mdctx); explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } } int ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) { const struct ssh_digest *digest = ssh_digest_by_alg(alg); u_int mdlen; if (digest == NULL) return SSH_ERR_INVALID_ARGUMENT; if (dlen > UINT_MAX) return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) return SSH_ERR_INVALID_ARGUMENT; mdlen = dlen; if (!EVP_Digest(m, mlen, d, &mdlen, digest->mdfunc(), NULL)) return SSH_ERR_LIBCRYPTO_ERROR; return 0; } int ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } #endif /* WITH_OPENSSL */ openssh-7.2p2/digest.h010064400017500001750000000050521267006270000131040ustar00djmdjm/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _DIGEST_H #define _DIGEST_H /* Maximum digest output length */ #define SSH_DIGEST_MAX_LENGTH 64 /* Digest algorithms */ #define SSH_DIGEST_MD5 0 #define SSH_DIGEST_RIPEMD160 1 #define SSH_DIGEST_SHA1 2 #define SSH_DIGEST_SHA256 3 #define SSH_DIGEST_SHA384 4 #define SSH_DIGEST_SHA512 5 #define SSH_DIGEST_MAX 6 struct sshbuf; struct ssh_digest_ctx; /* Looks up a digest algorithm by name */ int ssh_digest_alg_by_name(const char *name); /* Returns the algorithm name for a digest identifier */ const char *ssh_digest_alg_name(int alg); /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ size_t ssh_digest_bytes(int alg); /* Returns the block size of the digest, e.g. for implementing HMAC */ size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx); /* Copies internal state of digest of 'from' to 'to' */ int ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to); /* One-shot API */ int ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__buffer__, 4, 5))); int ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) __attribute__((__bounded__(__buffer__, 3, 4))); /* Update API */ struct ssh_digest_ctx *ssh_digest_start(int alg); int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) __attribute__((__bounded__(__buffer__, 2, 3))); int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b); int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) __attribute__((__bounded__(__buffer__, 2, 3))); void ssh_digest_free(struct ssh_digest_ctx *ctx); #endif /* _DIGEST_H */ openssh-7.2p2/dispatch.c010064400017500001750000000072761267006270000134310ustar00djmdjm/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 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 "includes.h" #include #include #include #include "ssh1.h" #include "ssh2.h" #include "log.h" #include "dispatch.h" #include "packet.h" #include "compat.h" #include "ssherr.h" int dispatch_protocol_error(int type, u_int32_t seq, void *ctx) { struct ssh *ssh = active_state; /* XXX */ int r; logit("dispatch_protocol_error: type %d seq %u", type, seq); if (!compat20) fatal("protocol error"); if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || (r = sshpkt_put_u32(ssh, seq)) != 0 || (r = sshpkt_send(ssh)) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) sshpkt_fatal(ssh, __func__, r); return 0; } int dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh) { logit("dispatch_protocol_ignore: type %d seq %u", type, seq); return 0; } void ssh_dispatch_init(struct ssh *ssh, dispatch_fn *dflt) { u_int i; for (i = 0; i < DISPATCH_MAX; i++) ssh->dispatch[i] = dflt; } void ssh_dispatch_range(struct ssh *ssh, u_int from, u_int to, dispatch_fn *fn) { u_int i; for (i = from; i <= to; i++) { if (i >= DISPATCH_MAX) break; ssh->dispatch[i] = fn; } } void ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn) { ssh->dispatch[type] = fn; } int ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done, void *ctxt) { int r; u_char type; u_int32_t seqnr; for (;;) { if (mode == DISPATCH_BLOCK) { r = ssh_packet_read_seqnr(ssh, &type, &seqnr); if (r != 0) return r; } else { r = ssh_packet_read_poll_seqnr(ssh, &type, &seqnr); if (r != 0) return r; if (type == SSH_MSG_NONE) return 0; } if (type > 0 && type < DISPATCH_MAX && ssh->dispatch[type] != NULL) { if (ssh->dispatch_skip_packets) { debug2("skipped packet (type %u)", type); ssh->dispatch_skip_packets--; continue; } /* XXX 'ssh' will replace 'ctxt' later */ r = (*ssh->dispatch[type])(type, seqnr, ctxt); if (r != 0) return r; } else { r = sshpkt_disconnect(ssh, "protocol error: rcvd type %d", type); if (r != 0) return r; return SSH_ERR_DISCONNECTED; } if (done != NULL && *done) return 0; } } void ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done, void *ctxt) { int r; if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0) sshpkt_fatal(ssh, __func__, r); } openssh-7.2p2/dispatch.h010064400017500001750000000044631267006270000134310ustar00djmdjm/* $OpenBSD: dispatch.h,v 1.12 2015/01/19 20:07:45 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 DISPATCH_H #define DISPATCH_H #define DISPATCH_MAX 255 enum { DISPATCH_BLOCK, DISPATCH_NONBLOCK }; struct ssh; typedef int dispatch_fn(int, u_int32_t, void *); int dispatch_protocol_error(int, u_int32_t, void *); int dispatch_protocol_ignore(int, u_int32_t, void *); void ssh_dispatch_init(struct ssh *, dispatch_fn *); void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *); void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *); #define dispatch_init(dflt) \ ssh_dispatch_init(active_state, (dflt)) #define dispatch_range(from, to, fn) \ ssh_dispatch_range(active_state, (from), (to), (fn)) #define dispatch_set(type, fn) \ ssh_dispatch_set(active_state, (type), (fn)) #define dispatch_run(mode, done, ctxt) \ ssh_dispatch_run_fatal(active_state, (mode), (done), (ctxt)) #endif openssh-7.2p2/dns.c010064400017500001750000000220541267006270000124050ustar00djmdjm/* $OpenBSD: dns.c,v 1.35 2015/08/20 22:32: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 #include #include #include #include #include #include #include #include "xmalloc.h" #include "sshkey.h" #include "ssherr.h" #include "dns.h" #include "log.h" #include "digest.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, size_t *digest_len, struct sshkey *key) { int r, success = 0; int fp_alg = -1; switch (key->type) { case KEY_RSA: *algorithm = SSHFP_KEY_RSA; if (!*digest_type) *digest_type = SSHFP_HASH_SHA1; break; case KEY_DSA: *algorithm = SSHFP_KEY_DSA; if (!*digest_type) *digest_type = SSHFP_HASH_SHA1; break; case KEY_ECDSA: *algorithm = SSHFP_KEY_ECDSA; if (!*digest_type) *digest_type = SSHFP_HASH_SHA256; break; case KEY_ED25519: *algorithm = SSHFP_KEY_ED25519; if (!*digest_type) *digest_type = SSHFP_HASH_SHA256; break; default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ *digest_type = SSHFP_HASH_RESERVED; /* 0 */ } switch (*digest_type) { case SSHFP_HASH_SHA1: fp_alg = SSH_DIGEST_SHA1; break; case SSHFP_HASH_SHA256: fp_alg = SSH_DIGEST_SHA256; break; default: *digest_type = SSHFP_HASH_RESERVED; /* 0 */ } if (*algorithm && *digest_type) { if ((r = sshkey_fingerprint_raw(key, fp_alg, digest, digest_len)) != 0) fatal("%s: sshkey_fingerprint_raw: %s", __func__, ssh_err(r)); success = 1; } else { *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, size_t *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 = 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; /* * We shouldn't ever get a null host but if we do then log an error * and return -1 which stops DNS key fingerprint processing. */ if (hostname == NULL) { error("is_numeric_hostname called with NULL hostname"); return -1; } memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo(hostname, NULL, &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, struct sshkey *hostkey, int *flags) { u_int counter; int result; struct rrsetinfo *fingerprints = NULL; u_int8_t hostkey_algorithm; u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; u_char *hostkey_digest; size_t hostkey_digest_len; u_int8_t dnskey_algorithm; u_int8_t dnskey_digest_type; u_char *dnskey_digest; size_t 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 default 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; } if (hostkey_digest_type != dnskey_digest_type) { hostkey_digest_type = dnskey_digest_type; free(hostkey_digest); /* Initialize host key parameters */ if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, &hostkey_digest, &hostkey_digest_len, hostkey)) { error("Error calculating key fingerprint."); freerrset(fingerprints); return -1; } } /* 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 && timingsafe_bcmp(hostkey_digest, dnskey_digest, hostkey_digest_len) == 0) *flags |= DNS_VERIFY_MATCH; } free(dnskey_digest); } free(hostkey_digest); /* from sshkey_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, struct sshkey *key, FILE *f, int generic) { u_int8_t rdata_pubkey_algorithm = 0; u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; u_int8_t dtype; u_char *rdata_digest; size_t i, rdata_digest_len; int success = 0; for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { rdata_digest_type = dtype; if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, &rdata_digest, &rdata_digest_len, key)) { if (generic) { fprintf(f, "%s IN TYPE%d \\# %zu %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"); free(rdata_digest); /* from sshkey_fingerprint_raw() */ success = 1; } } /* No SSHFP record was generated at all */ if (success == 0) { error("%s: unsupported algorithm and/or digest_type", __func__); } return success; } openssh-7.2p2/dns.h010064400017500001750000000040051267006270000124060ustar00djmdjm/* $OpenBSD: dns.h,v 1.15 2015/05/08 06:45:13 djm 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 = 0, SSHFP_KEY_RSA = 1, SSHFP_KEY_DSA = 2, SSHFP_KEY_ECDSA = 3, SSHFP_KEY_ED25519 = 4 }; enum sshfp_hashes { SSHFP_HASH_RESERVED = 0, SSHFP_HASH_SHA1 = 1, SSHFP_HASH_SHA256 = 2, SSHFP_HASH_MAX = 3 }; #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 *, struct sshkey *, int *); int export_dns_rr(const char *, struct sshkey *, FILE *, int); #endif /* DNS_H */ openssh-7.2p2/ed25519.c010064400017500001750000000061431267006270000126200ustar00djmdjm/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c */ #include "includes.h" #include "crypto_api.h" #include "ge25519.h" static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) { unsigned long long i; for (i = 0;i < 32;++i) playground[i] = sm[i]; for (i = 32;i < 64;++i) playground[i] = pk[i-32]; for (i = 64;i < smlen;++i) playground[i] = sm[i]; crypto_hash_sha512(hram,playground,smlen); } int crypto_sign_ed25519_keypair( unsigned char *pk, unsigned char *sk ) { sc25519 scsk; ge25519 gepk; unsigned char extsk[64]; int i; randombytes(sk, 32); crypto_hash_sha512(extsk, sk, 32); extsk[0] &= 248; extsk[31] &= 127; extsk[31] |= 64; sc25519_from32bytes(&scsk,extsk); ge25519_scalarmult_base(&gepk, &scsk); ge25519_pack(pk, &gepk); for(i=0;i<32;i++) sk[32 + i] = pk[i]; return 0; } int crypto_sign_ed25519( unsigned char *sm,unsigned long long *smlen, const unsigned char *m,unsigned long long mlen, const unsigned char *sk ) { sc25519 sck, scs, scsk; ge25519 ger; unsigned char r[32]; unsigned char s[32]; unsigned char extsk[64]; unsigned long long i; unsigned char hmg[crypto_hash_sha512_BYTES]; unsigned char hram[crypto_hash_sha512_BYTES]; crypto_hash_sha512(extsk, sk, 32); extsk[0] &= 248; extsk[31] &= 127; extsk[31] |= 64; *smlen = mlen+64; for(i=0;i #include #ifdef HAVE_SYS_UN_H # include #endif #include #include #include #include #include #include #include /* for offsetof */ #include #include #include #include "openbsd-compat/openssl-compat.h" #include "ssh.h" #include "misc.h" #include "xmalloc.h" #include "atomicio.h" #include "pathnames.h" #include "log.h" #include "buffer.h" /* * Portable OpenSSH PRNG seeding: * If OpenSSL has not "internally seeded" itself (e.g. pulled data from * /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from * PRNGd. */ #ifndef OPENSSL_PRNG_ONLY #define RANDOM_SEED_SIZE 48 /* * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon * listening either on 'tcp_port', or via Unix domain socket at * * 'socket_path'. * Either a non-zero tcp_port or a non-null socket_path must be * supplied. * Returns 0 on success, -1 on error */ int get_random_bytes_prngd(unsigned char *buf, int len, unsigned short tcp_port, char *socket_path) { int fd, addr_len, rval, errors; u_char msg[2]; struct sockaddr_storage addr; struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr; mysig_t old_sigpipe; /* Sanity checks */ if (socket_path == NULL && tcp_port == 0) fatal("You must specify a port or a socket"); if (socket_path != NULL && strlen(socket_path) >= sizeof(addr_un->sun_path)) fatal("Random pool path is too long"); if (len <= 0 || len > 255) fatal("Too many bytes (%d) to read from PRNGD", len); memset(&addr, '\0', sizeof(addr)); if (tcp_port != 0) { addr_in->sin_family = AF_INET; addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in->sin_port = htons(tcp_port); addr_len = sizeof(*addr_in); } else { addr_un->sun_family = AF_UNIX; strlcpy(addr_un->sun_path, socket_path, sizeof(addr_un->sun_path)); addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path) + 1; } old_sigpipe = mysignal(SIGPIPE, SIG_IGN); errors = 0; rval = -1; reopen: fd = socket(addr.ss_family, SOCK_STREAM, 0); if (fd == -1) { error("Couldn't create socket: %s", strerror(errno)); goto done; } if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { if (tcp_port != 0) { error("Couldn't connect to PRNGD port %d: %s", tcp_port, strerror(errno)); } else { error("Couldn't connect to PRNGD socket \"%s\": %s", addr_un->sun_path, strerror(errno)); } goto done; } /* Send blocking read request to PRNGD */ msg[0] = 0x02; msg[1] = len; if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) { if (errno == EPIPE && errors < 10) { close(fd); errors++; goto reopen; } error("Couldn't write to PRNGD socket: %s", strerror(errno)); goto done; } if (atomicio(read, fd, buf, len) != (size_t)len) { if (errno == EPIPE && errors < 10) { close(fd); errors++; goto reopen; } error("Couldn't read from PRNGD socket: %s", strerror(errno)); goto done; } rval = 0; done: mysignal(SIGPIPE, old_sigpipe); if (fd != -1) close(fd); return rval; } static int seed_from_prngd(unsigned char *buf, size_t bytes) { #ifdef PRNGD_PORT debug("trying egd/prngd port %d", PRNGD_PORT); if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0) return 0; #endif #ifdef PRNGD_SOCKET debug("trying egd/prngd socket %s", PRNGD_SOCKET); if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0) return 0; #endif return -1; } void rexec_send_rng_seed(Buffer *m) { u_char buf[RANDOM_SEED_SIZE]; if (RAND_bytes(buf, sizeof(buf)) <= 0) { error("Couldn't obtain random bytes (error %ld)", ERR_get_error()); buffer_put_string(m, "", 0); } else buffer_put_string(m, buf, sizeof(buf)); } void rexec_recv_rng_seed(Buffer *m) { u_char *buf; u_int len; buf = buffer_get_string_ret(m, &len); if (buf != NULL) { debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len); RAND_add(buf, len, len); } } #endif /* OPENSSL_PRNG_ONLY */ void seed_rng(void) { #ifndef OPENSSL_PRNG_ONLY unsigned char buf[RANDOM_SEED_SIZE]; #endif if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay())) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); return; } if (seed_from_prngd(buf, sizeof(buf)) == -1) fatal("Could not obtain seed from PRNGd"); RAND_add(buf, sizeof(buf), sizeof(buf)); memset(buf, '\0', sizeof(buf)); #endif /* OPENSSL_PRNG_ONLY */ if (RAND_status() != 1) fatal("PRNG is not seeded"); } #else /* WITH_OPENSSL */ /* Handled in arc4random() */ void seed_rng(void) { } #endif /* WITH_OPENSSL */ openssh-7.2p2/entropy.h010064400017500001750000000030331267006270000133220ustar00djmdjm/* * Copyright (c) 1999-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. */ /* $Id: entropy.h,v 1.6 2011/09/09 01:29:41 dtucker Exp $ */ #ifndef _RANDOMS_H #define _RANDOMS_H #include "buffer.h" void seed_rng(void); void rexec_send_rng_seed(Buffer *); void rexec_recv_rng_seed(Buffer *); #endif /* _RANDOMS_H */ openssh-7.2p2/fatal.c010064400017500001750000000032051267006270000127050ustar00djmdjm/* $OpenBSD: fatal.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #include "log.h" /* Fatal messages. This function never returns. */ void fatal(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_FATAL, fmt, args); va_end(args); cleanup_exit(255); } openssh-7.2p2/fe25519.c010064400017500001750000000202121267006270000126130ustar00djmdjm/* $OpenBSD: fe25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c */ #include "includes.h" #define WINDOWSIZE 1 /* Should be 1,2, or 4 */ #define WINDOWMASK ((1<>= 31; /* 1: yes; 0: no */ return x; } static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ { unsigned int x = a; x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ x >>= 31; /* 0: yes; 1: no */ x ^= 1; /* 1: yes; 0: no */ return x; } static crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; } static crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); } static void reduce_add_sub(fe25519 *r) { crypto_uint32 t; int i,rep; for(rep=0;rep<4;rep++) { t = r->v[31] >> 7; r->v[31] &= 127; t = times19(t); r->v[0] += t; for(i=0;i<31;i++) { t = r->v[i] >> 8; r->v[i+1] += t; r->v[i] &= 255; } } } static void reduce_mul(fe25519 *r) { crypto_uint32 t; int i,rep; for(rep=0;rep<2;rep++) { t = r->v[31] >> 7; r->v[31] &= 127; t = times19(t); r->v[0] += t; for(i=0;i<31;i++) { t = r->v[i] >> 8; r->v[i+1] += t; r->v[i] &= 255; } } } /* reduction modulo 2^255-19 */ void fe25519_freeze(fe25519 *r) { int i; crypto_uint32 m = equal(r->v[31],127); for(i=30;i>0;i--) m &= equal(r->v[i],255); m &= ge(r->v[0],237); m = -m; r->v[31] -= m&127; for(i=30;i>0;i--) r->v[i] -= m&255; r->v[0] -= m&237; } void fe25519_unpack(fe25519 *r, const unsigned char x[32]) { int i; for(i=0;i<32;i++) r->v[i] = x[i]; r->v[31] &= 127; } /* Assumes input x being reduced below 2^255 */ void fe25519_pack(unsigned char r[32], const fe25519 *x) { int i; fe25519 y = *x; fe25519_freeze(&y); for(i=0;i<32;i++) r[i] = y.v[i]; } int fe25519_iszero(const fe25519 *x) { int i; int r; fe25519 t = *x; fe25519_freeze(&t); r = equal(t.v[0],0); for(i=1;i<32;i++) r &= equal(t.v[i],0); return r; } int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) { int i; fe25519 t1 = *x; fe25519 t2 = *y; fe25519_freeze(&t1); fe25519_freeze(&t2); for(i=0;i<32;i++) if(t1.v[i] != t2.v[i]) return 0; return 1; } void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) { int i; crypto_uint32 mask = b; mask = -mask; for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]); } unsigned char fe25519_getparity(const fe25519 *x) { fe25519 t = *x; fe25519_freeze(&t); return t.v[0] & 1; } void fe25519_setone(fe25519 *r) { int i; r->v[0] = 1; for(i=1;i<32;i++) r->v[i]=0; } void fe25519_setzero(fe25519 *r) { int i; for(i=0;i<32;i++) r->v[i]=0; } void fe25519_neg(fe25519 *r, const fe25519 *x) { fe25519 t; int i; for(i=0;i<32;i++) t.v[i]=x->v[i]; fe25519_setzero(r); fe25519_sub(r, r, &t); } void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) { int i; for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; reduce_add_sub(r); } void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) { int i; crypto_uint32 t[32]; t[0] = x->v[0] + 0x1da; t[31] = x->v[31] + 0xfe; for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe; for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i]; reduce_add_sub(r); } void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) { int i,j; crypto_uint32 t[63]; for(i=0;i<63;i++)t[i] = 0; for(i=0;i<32;i++) for(j=0;j<32;j++) t[i+j] += x->v[i] * y->v[j]; for(i=32;i<63;i++) r->v[i-32] = t[i-32] + times38(t[i]); r->v[31] = t[31]; /* result now in r[0]...r[31] */ reduce_mul(r); } void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); } void fe25519_invert(fe25519 *r, const fe25519 *x) { fe25519 z2; fe25519 z9; fe25519 z11; fe25519 z2_5_0; fe25519 z2_10_0; fe25519 z2_20_0; fe25519 z2_50_0; fe25519 z2_100_0; fe25519 t0; fe25519 t1; int i; /* 2 */ fe25519_square(&z2,x); /* 4 */ fe25519_square(&t1,&z2); /* 8 */ fe25519_square(&t0,&t1); /* 9 */ fe25519_mul(&z9,&t0,x); /* 11 */ fe25519_mul(&z11,&z9,&z2); /* 22 */ fe25519_square(&t0,&z11); /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9); /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0); /* 2^7 - 2^2 */ fe25519_square(&t1,&t0); /* 2^8 - 2^3 */ fe25519_square(&t0,&t1); /* 2^9 - 2^4 */ fe25519_square(&t1,&t0); /* 2^10 - 2^5 */ fe25519_square(&t0,&t1); /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0); /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0); /* 2^12 - 2^2 */ fe25519_square(&t1,&t0); /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0); /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0); /* 2^22 - 2^2 */ fe25519_square(&t1,&t0); /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0); /* 2^41 - 2^1 */ fe25519_square(&t1,&t0); /* 2^42 - 2^2 */ fe25519_square(&t0,&t1); /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0); /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0); /* 2^52 - 2^2 */ fe25519_square(&t1,&t0); /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0); /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0); /* 2^102 - 2^2 */ fe25519_square(&t0,&t1); /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0); /* 2^201 - 2^1 */ fe25519_square(&t0,&t1); /* 2^202 - 2^2 */ fe25519_square(&t1,&t0); /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0); /* 2^251 - 2^1 */ fe25519_square(&t1,&t0); /* 2^252 - 2^2 */ fe25519_square(&t0,&t1); /* 2^253 - 2^3 */ fe25519_square(&t1,&t0); /* 2^254 - 2^4 */ fe25519_square(&t0,&t1); /* 2^255 - 2^5 */ fe25519_square(&t1,&t0); /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11); } void fe25519_pow2523(fe25519 *r, const fe25519 *x) { fe25519 z2; fe25519 z9; fe25519 z11; fe25519 z2_5_0; fe25519 z2_10_0; fe25519 z2_20_0; fe25519 z2_50_0; fe25519 z2_100_0; fe25519 t; int i; /* 2 */ fe25519_square(&z2,x); /* 4 */ fe25519_square(&t,&z2); /* 8 */ fe25519_square(&t,&t); /* 9 */ fe25519_mul(&z9,&t,x); /* 11 */ fe25519_mul(&z11,&z9,&z2); /* 22 */ fe25519_square(&t,&z11); /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); /* 2^41 - 2^1 */ fe25519_square(&t,&t); /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); /* 2^201 - 2^1 */ fe25519_square(&t,&t); /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); /* 2^251 - 2^1 */ fe25519_square(&t,&t); /* 2^252 - 2^2 */ fe25519_square(&t,&t); /* 2^252 - 3 */ fe25519_mul(r,&t,x); } openssh-7.2p2/fe25519.h010064400017500001750000000044741267006270000126340ustar00djmdjm/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h */ #ifndef FE25519_H #define FE25519_H #include "crypto_api.h" #define fe25519 crypto_sign_ed25519_ref_fe25519 #define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze #define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack #define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack #define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero #define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime #define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov #define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone #define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero #define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg #define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity #define fe25519_add crypto_sign_ed25519_ref_fe25519_add #define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub #define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul #define fe25519_square crypto_sign_ed25519_ref_fe25519_square #define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert #define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523 typedef struct { crypto_uint32 v[32]; } fe25519; void fe25519_freeze(fe25519 *r); void fe25519_unpack(fe25519 *r, const unsigned char x[32]); void fe25519_pack(unsigned char r[32], const fe25519 *x); int fe25519_iszero(const fe25519 *x); int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y); void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); void fe25519_setone(fe25519 *r); void fe25519_setzero(fe25519 *r); void fe25519_neg(fe25519 *r, const fe25519 *x); unsigned char fe25519_getparity(const fe25519 *x); void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); void fe25519_square(fe25519 *r, const fe25519 *x); void fe25519_invert(fe25519 *r, const fe25519 *x); void fe25519_pow2523(fe25519 *r, const fe25519 *x); #endif openssh-7.2p2/fixalgorithms010075500017500001750000000006461267006270000142660ustar00djmdjm#!/bin/sh # # fixciphers - remove unsupported ciphers from man pages. # Usage: fixpaths /path/to/sed cipher1 [cipher2] outfile # # Author: Darren Tucker (dtucker at zip com.au). Placed in the public domain. die() { echo $* exit -1 } SED=$1 shift for c in $*; do subs="$subs -e /.Dq.$c.*$/d" subs="$subs -e s/$c,//g" done # now remove any entirely empty lines subs="$subs -e /^$/d" ${SED} $subs exit 0 openssh-7.2p2/fixpaths010075500017500001750000000007631267006270000132340ustar00djmdjm#!/bin/sh # # fixpaths - substitute makefile variables into text files # Usage: fixpaths -Dsomething=somethingelse ... die() { echo $* exit -1 } test -n "`echo $1|grep -- -D`" || \ die $0: nothing to do - no substitutions listed! test -n "`echo $1|grep -- '-D[^=]\+=[^ ]\+'`" || \ die $0: error in command line arguments. test -n "`echo $*|grep -- ' [^-]'`" || \ die Usage: $0 '[-Dstring=replacement] [[infile] ...]' sed `echo $*|sed -e 's/-D\([^=]\+\)=\([^ ]*\)/-e s=\1=\2=g/g'` exit 0 openssh-7.2p2/fixprogs010075500017500001750000000031201267006270000132350ustar00djmdjm#!/usr/bin/perl # # fixprogs - run through the list of entropy commands and # score out the losers # $entscale = 50; # divisor for optional entropy measurement sub usage { return("Usage: $0 \n"); } if (($#ARGV == -1) || ($#ARGV>1)) { die(&usage); } # 'undocumented' option - run ent (in second param) on the output if ($#ARGV==1) { $entcmd=$ARGV[1] } else { $entcmd = "" }; $infilename = $ARGV[0]; if (!open(IN, "<".$infilename)) { die("Couldn't open input file"); } $outfilename=$infilename.".out"; if (!open(OUT, ">$outfilename")) { die("Couldn't open output file $outfilename"); } @infile=; select(OUT); $|=1; select(STDOUT); foreach (@infile) { if (/^\s*\#/ || /^\s*$/) { print OUT; next; } ($cmd, $path, $est) = /^\"([^\"]+)\"\s+([\w\/_-]+)\s+([\d\.\-]+)/o; @args = split(/ /, $cmd); if (! ($pid = fork())) { # child close STDIN; close STDOUT; close STDERR; open (STDIN, "/dev/null"); open (STDERR, ">/dev/null"); exec $path @args; exit 1; # shouldn't be here } # parent waitpid ($pid, 0); $ret=$? >> 8; if ($ret != 0) { $path = "undef"; } else { if ($entcmd ne "") { # now try to run ent on the command $mostargs=join(" ", splice(@args,1)); print "Evaluating '$path $mostargs'\n"; @ent = qx{$path $mostargs | $entcmd -b -t}; @ent = grep(/^1,/, @ent); ($null, $null, $rate) = split(/,/, $ent[0]); $est = $rate / $entscale; # scale the estimate back } } print OUT "\"$cmd\" $path $est\n"; } close(IN); openssh-7.2p2/ge25519.c010064400017500001750000000260561267006270000126300ustar00djmdjm/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c */ #include "includes.h" #include "fe25519.h" #include "sc25519.h" #include "ge25519.h" /* * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555 * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960); */ /* d */ static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}}; /* 2*d */ static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}}; /* sqrt(-1) */ static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}}; #define ge25519_p3 ge25519 typedef struct { fe25519 x; fe25519 z; fe25519 y; fe25519 t; } ge25519_p1p1; typedef struct { fe25519 x; fe25519 y; fe25519 z; } ge25519_p2; typedef struct { fe25519 x; fe25519 y; } ge25519_aff; /* Packed coordinates of the base point */ const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}}, {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}}; /* Multiples of the base point in affine representation */ static const ge25519_aff ge25519_base_multiples_affine[425] = { #include "ge25519_base.data" }; static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) { fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->z, &p->z, &p->t); } static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) { p1p1_to_p2((ge25519_p2 *)r, p); fe25519_mul(&r->t, &p->x, &p->y); } static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q) { fe25519 a,b,t1,t2,c,d,e,f,g,h,qt; fe25519_mul(&qt, &q->x, &q->y); fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */ fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */ fe25519_sub(&t1, &q->y, &q->x); fe25519_add(&t2, &q->y, &q->x); fe25519_mul(&a, &a, &t1); fe25519_mul(&b, &b, &t2); fe25519_sub(&e, &b, &a); /* E = B-A */ fe25519_add(&h, &b, &a); /* H = B+A */ fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */ fe25519_mul(&c, &c, &ge25519_ec2d); fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */ fe25519_sub(&f, &d, &c); /* F = D-C */ fe25519_add(&g, &d, &c); /* G = D+C */ fe25519_mul(&r->x, &e, &f); fe25519_mul(&r->y, &h, &g); fe25519_mul(&r->z, &g, &f); fe25519_mul(&r->t, &e, &h); } static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q) { fe25519 a, b, c, d, t; fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */ fe25519_sub(&t, &q->y, &q->x); fe25519_mul(&a, &a, &t); fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */ fe25519_add(&t, &q->x, &q->y); fe25519_mul(&b, &b, &t); fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */ fe25519_mul(&c, &c, &ge25519_ec2d); fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */ fe25519_add(&d, &d, &d); fe25519_sub(&r->x, &b, &a); /* E = B-A */ fe25519_sub(&r->t, &d, &c); /* F = D-C */ fe25519_add(&r->z, &d, &c); /* G = D+C */ fe25519_add(&r->y, &b, &a); /* H = B+A */ } /* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) { fe25519 a,b,c,d; fe25519_square(&a, &p->x); fe25519_square(&b, &p->y); fe25519_square(&c, &p->z); fe25519_add(&c, &c, &c); fe25519_neg(&d, &a); fe25519_add(&r->x, &p->x, &p->y); fe25519_square(&r->x, &r->x); fe25519_sub(&r->x, &r->x, &a); fe25519_sub(&r->x, &r->x, &b); fe25519_add(&r->z, &d, &b); fe25519_sub(&r->t, &r->z, &c); fe25519_sub(&r->y, &d, &b); } /* Constant-time version of: if(b) r = p */ static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) { fe25519_cmov(&r->x, &p->x, b); fe25519_cmov(&r->y, &p->y, b); } static unsigned char equal(signed char b,signed char c) { unsigned char ub = b; unsigned char uc = c; unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ crypto_uint32 y = x; /* 0: yes; 1..255: no */ y -= 1; /* 4294967295: yes; 0..254: no */ y >>= 31; /* 1: yes; 0: no */ return y; } static unsigned char negative(signed char b) { unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ x >>= 63; /* 1: yes; 0: no */ return x; } static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b) { /* constant time */ fe25519 v; *t = ge25519_base_multiples_affine[5*pos+0]; cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1)); cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2)); cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3)); cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4)); fe25519_neg(&v, &t->x); fe25519_cmov(&t->x, &v, negative(b)); } static void setneutral(ge25519 *r) { fe25519_setzero(&r->x); fe25519_setone(&r->y); fe25519_setone(&r->z); fe25519_setzero(&r->t); } /* ******************************************************************** * EXPORTED FUNCTIONS ******************************************************************** */ /* return 0 on success, -1 otherwise */ int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) { unsigned char par; fe25519 t, chk, num, den, den2, den4, den6; fe25519_setone(&r->z); par = p[31] >> 7; fe25519_unpack(&r->y, p); fe25519_square(&num, &r->y); /* x = y^2 */ fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */ fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ /* Computation of sqrt(num/den) */ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ fe25519_square(&den2, &den); fe25519_square(&den4, &den2); fe25519_mul(&den6, &den4, &den2); fe25519_mul(&t, &den6, &num); fe25519_mul(&t, &t, &den); fe25519_pow2523(&t, &t); /* 2. computation of r->x = t * num * den^3 */ fe25519_mul(&t, &t, &num); fe25519_mul(&t, &t, &den); fe25519_mul(&t, &t, &den); fe25519_mul(&r->x, &t, &den); /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */ fe25519_square(&chk, &r->x); fe25519_mul(&chk, &chk, &den); if (!fe25519_iseq_vartime(&chk, &num)) fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1); /* 4. Now we have one of the two square roots, except if input was not a square */ fe25519_square(&chk, &r->x); fe25519_mul(&chk, &chk, &den); if (!fe25519_iseq_vartime(&chk, &num)) return -1; /* 5. Choose the desired square root according to parity: */ if(fe25519_getparity(&r->x) != (1-par)) fe25519_neg(&r->x, &r->x); fe25519_mul(&r->t, &r->x, &r->y); return 0; } void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) { fe25519 tx, ty, zi; fe25519_invert(&zi, &p->z); fe25519_mul(&tx, &p->x, &zi); fe25519_mul(&ty, &p->y, &zi); fe25519_pack(r, &ty); r[31] ^= fe25519_getparity(&tx) << 7; } int ge25519_isneutral_vartime(const ge25519_p3 *p) { int ret = 1; if(!fe25519_iszero(&p->x)) ret = 0; if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0; return ret; } /* computes [s1]p1 + [s2]p2 */ void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2) { ge25519_p1p1 tp1p1; ge25519_p3 pre[16]; unsigned char b[127]; int i; /* precomputation s2 s1 */ setneutral(pre); /* 00 00 */ pre[1] = *p1; /* 00 01 */ dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */ add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */ pre[4] = *p2; /* 01 00 */ add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */ add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */ add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */ dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */ add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */ dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */ add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */ add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */ add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */ add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */ add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */ sc25519_2interleave2(b,s1,s2); /* scalar multiplication */ *r = pre[b[126]]; for(i=125;i>=0;i--) { dbl_p1p1(&tp1p1, (ge25519_p2 *)r); p1p1_to_p2((ge25519_p2 *) r, &tp1p1); dbl_p1p1(&tp1p1, (ge25519_p2 *)r); if(b[i]!=0) { p1p1_to_p3(r, &tp1p1); add_p1p1(&tp1p1, r, &pre[b[i]]); } if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1); else p1p1_to_p3(r, &tp1p1); } } void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) { signed char b[85]; int i; ge25519_aff t; sc25519_window3(b,s); choose_t((ge25519_aff *)r, 0, b[0]); fe25519_setone(&r->z); fe25519_mul(&r->t, &r->x, &r->y); for(i=1;i<85;i++) { choose_t(&t, (unsigned long long) i, b[i]); ge25519_mixadd2(r, &t); } } openssh-7.2p2/ge25519.h010064400017500001750000000025501267006270000126260ustar00djmdjm/* $OpenBSD: ge25519.h,v 1.4 2015/02/16 18:26:26 miod Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h */ #ifndef GE25519_H #define GE25519_H #include "fe25519.h" #include "sc25519.h" #define ge25519 crypto_sign_ed25519_ref_ge25519 #define ge25519_base crypto_sign_ed25519_ref_ge25519_base #define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime #define ge25519_pack crypto_sign_ed25519_ref_pack #define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime #define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime #define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base typedef struct { fe25519 x; fe25519 y; fe25519 z; fe25519 t; } ge25519; extern const ge25519 ge25519_base; int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); void ge25519_pack(unsigned char r[32], const ge25519 *p); int ge25519_isneutral_vartime(const ge25519 *p); void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2); void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); #endif openssh-7.2p2/ge25519_base.data010064400017500001750000005111601267006270000143040ustar00djmdjm/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data */ {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} , {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}}, {{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} , {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}}, {{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} , {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}}, {{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} , {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} , {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}}, {{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} , {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}}, {{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} , {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}}, {{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} , {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} , {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}}, {{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} , {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}}, {{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} , {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}}, {{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} , {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} , {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}}, {{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} , {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}}, {{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} , {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}}, {{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} , {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} , {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}}, {{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} , {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}}, {{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} , {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}}, {{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} , {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} , {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}}, {{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} , {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}}, {{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} , {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}}, {{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} , {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} , {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}}, {{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} , {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}}, {{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} , {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}}, {{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} , {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} , {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}}, {{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} , {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}}, {{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} , {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}}, {{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} , {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} , {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}}, {{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} , {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}}, {{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} , {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}}, {{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} , {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} , {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}}, {{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} , {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}}, {{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} , {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}}, {{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} , {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} , {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}}, {{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} , {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}}, {{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} , {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}}, {{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} , {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} , {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}}, {{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} , {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}}, {{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} , {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}}, {{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} , {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} , {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}}, {{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} , {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}}, {{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} , {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}}, {{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} , {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} , {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}}, {{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} , {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}}, {{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} , {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}}, {{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} , {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} , {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}}, {{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} , {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}}, {{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} , {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}}, {{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} , {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} , {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}}, {{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} , {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}}, {{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} , {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}}, {{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} , {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} , {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}}, {{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} , {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}}, {{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} , {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}}, {{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} , {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} , {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}}, {{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} , {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}}, {{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} , {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}}, {{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} , {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} , {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}}, {{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} , {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}}, {{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} , {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}}, {{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} , {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} , {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}}, {{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} , {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}}, {{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} , {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}}, {{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} , {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} , {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}}, {{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} , {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}}, {{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} , {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}}, {{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} , {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} , {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}}, {{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} , {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}}, {{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} , {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}}, {{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} , {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} , {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}}, {{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} , {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}}, {{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} , {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}}, {{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} , {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} , {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}}, {{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} , {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}}, {{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} , {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}}, {{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} , {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} , {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}}, {{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} , {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}}, {{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} , {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}}, {{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} , {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} , {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}}, {{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} , {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}}, {{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} , {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}}, {{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} , {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} , {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}}, {{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} , {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}}, {{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} , {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}}, {{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} , {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} , {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}}, {{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} , {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}}, {{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} , {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}}, {{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} , {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} , {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}}, {{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} , {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}}, {{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} , {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}}, {{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} , {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} , {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}}, {{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} , {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}}, {{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} , {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}}, {{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} , {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} , {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}}, {{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} , {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}}, {{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} , {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}}, {{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} , {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} , {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}}, {{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} , {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}}, {{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} , {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}}, {{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} , {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} , {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}}, {{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} , {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}}, {{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} , {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}}, {{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} , {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} , {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}}, {{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} , {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}}, {{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} , {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}}, {{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} , {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} , {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}}, {{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} , {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}}, {{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} , {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}}, {{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} , {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} , {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}}, {{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} , {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}}, {{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} , {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}}, {{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} , {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} , {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}}, {{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} , {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}}, {{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} , {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}}, {{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} , {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} , {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}}, {{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} , {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}}, {{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} , {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}}, {{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} , {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} , {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}}, {{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} , {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}}, {{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} , {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}}, {{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} , {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} , {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}}, {{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} , {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}}, {{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} , {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}}, {{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} , {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} , {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}}, {{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} , {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}}, {{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} , {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}}, {{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} , {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} , {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}}, {{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} , {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}}, {{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} , {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}}, {{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} , {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} , {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}}, {{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} , {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}}, {{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} , {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}}, {{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} , {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} , {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}}, {{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} , {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}}, {{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} , {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}}, {{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} , {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} , {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}}, {{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} , {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}}, {{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} , {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}}, {{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} , {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} , {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}}, {{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} , {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}}, {{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} , {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}}, {{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} , {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} , {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}}, {{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} , {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}}, {{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} , {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}}, {{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} , {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} , {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}}, {{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} , {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}}, {{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} , {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}}, {{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} , {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} , {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}}, {{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} , {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}}, {{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} , {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}}, {{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} , {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} , {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}}, {{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} , {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}}, {{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} , {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}}, {{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} , {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} , {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}}, {{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} , {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}}, {{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} , {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}}, {{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} , {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} , {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}}, {{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} , {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}}, {{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} , {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}}, {{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} , {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} , {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}}, {{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} , {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}}, {{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} , {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}}, {{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} , {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} , {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}}, {{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} , {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}}, {{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} , {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}}, {{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} , {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} , {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}}, {{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} , {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}}, {{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} , {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}}, {{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} , {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} , {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}}, {{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} , {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}}, {{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} , {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}}, {{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} , {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} , {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}}, {{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} , {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}}, {{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} , {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}}, {{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} , {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} , {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}}, {{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} , {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}}, {{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} , {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}}, {{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} , {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} , {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}}, {{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} , {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}}, {{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} , {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}}, {{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} , {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} , {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}}, {{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} , {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}}, {{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} , {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}}, {{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} , {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} , {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}}, {{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} , {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}}, {{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} , {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}}, {{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} , {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} , {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}}, {{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} , {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}}, {{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} , {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}}, {{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} , {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} , {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}}, {{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} , {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}}, {{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} , {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}}, {{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} , {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} , {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}}, {{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} , {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}}, {{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} , {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}}, {{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} , {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} , {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}}, {{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} , {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}}, {{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} , {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}}, {{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} , {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} , {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}}, {{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} , {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}}, {{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} , {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}}, {{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} , {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} , {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}}, {{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} , {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}}, {{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} , {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}}, {{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} , {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} , {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}}, {{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} , {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}}, {{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} , {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}}, {{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} , {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} , {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}}, {{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} , {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}}, {{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} , {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}}, {{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} , {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} , {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}}, {{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} , {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}}, {{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} , {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}}, {{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} , {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} , {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}}, {{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} , {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}}, {{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} , {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}}, {{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} , {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} , {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}}, {{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} , {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}}, {{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} , {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}}, {{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} , {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} , {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}}, {{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} , {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}}, {{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} , {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}}, {{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} , {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} , {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}}, {{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} , {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}}, {{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} , {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}}, {{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} , {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} , {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}}, {{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} , {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}}, {{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} , {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}}, {{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} , {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} , {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}}, {{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} , {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}}, {{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} , {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}}, {{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} , {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} , {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}}, {{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} , {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}}, {{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} , {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}}, {{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} , {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} , {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}}, {{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} , {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}}, {{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} , {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}}, {{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} , {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} , {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}}, {{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} , {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}}, {{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} , {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}}, {{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} , {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} , {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}}, {{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} , {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}}, {{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} , {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}}, {{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} , {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} , {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}}, {{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} , {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}}, {{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} , {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}}, {{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} , {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} , {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}}, {{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} , {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}}, {{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} , {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}}, {{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} , {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} , {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}}, {{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} , {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}}, {{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} , {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}}, {{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} , {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} , {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}}, {{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} , {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}}, {{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} , {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}}, {{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} , {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}}, {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, {{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} , {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}}, {{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} , {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}}, {{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} , {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}}, {{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} , {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}} openssh-7.2p2/groupaccess.c010064400017500001750000000065501267006270000141420ustar00djmdjm/* $OpenBSD: groupaccess.c,v 1.16 2015/05/04 06:10:48 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. 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 #include #include #include #include #include #include #include "xmalloc.h" #include "groupaccess.h" #include "match.h" #include "log.h" static int ngroups; static char **groups_byname; /* * Initialize group access list for user with primary (base) and * supplementary groups. Return the number of groups in the list. */ int ga_init(const char *user, gid_t base) { gid_t *groups_bygid; int i, j; struct group *gr; if (ngroups > 0) ga_free(); ngroups = NGROUPS_MAX; #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); #endif groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) logit("getgrouplist: groups list too small"); for (i = 0, j = 0; i < ngroups; i++) if ((gr = getgrgid(groups_bygid[i])) != NULL) groups_byname[j++] = xstrdup(gr->gr_name); free(groups_bygid); return (ngroups = j); } /* * Return 1 if one of user's groups is contained in groups. * Return 0 otherwise. Use match_pattern() for string comparison. */ int ga_match(char * const *groups, int n) { int i, j; for (i = 0; i < ngroups; i++) for (j = 0; j < n; j++) if (match_pattern(groups_byname[i], groups[j])) return 1; return 0; } /* * Return 1 if one of user's groups matches group_pattern list. * Return 0 on negated or no match. */ int ga_match_pattern_list(const char *group_pattern) { int i, found = 0; for (i = 0; i < ngroups; i++) { switch (match_pattern_list(groups_byname[i], group_pattern, 0)) { case -1: return 0; /* Negated match wins */ case 0: continue; case 1: found = 1; } } return found; } /* * Free memory allocated for group access list. */ void ga_free(void) { int i; if (ngroups > 0) { for (i = 0; i < ngroups; i++) free(groups_byname[i]); ngroups = 0; free(groups_byname); } } openssh-7.2p2/groupaccess.h010064400017500001750000000030421267006270000141400ustar00djmdjm/* $OpenBSD: groupaccess.h,v 1.8 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. 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 GROUPACCESS_H #define GROUPACCESS_H int ga_init(const char *, gid_t); int ga_match(char * const *, int); int ga_match_pattern_list(const char *); void ga_free(void); #endif openssh-7.2p2/gss-genr.c010064400017500001750000000165201267006270000133470ustar00djmdjm/* $OpenBSD: gss-genr.c,v 1.23 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 #include #include #include #include #include #include #include "xmalloc.h" #include "buffer.h" #include "log.h" #include "ssh2.h" #include "ssh-gss.h" extern u_char *session_id2; extern u_int session_id2_len; /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) { return (ctx != NULL && ctx->oid != GSS_C_NO_OID && ctx->oid->length == len && memcmp(ctx->oid->elements, data, len) == 0); } /* Set the contexts OID from a data stream */ void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) { if (ctx->oid != GSS_C_NO_OID) { free(ctx->oid->elements); free(ctx->oid); } ctx->oid = xcalloc(1, sizeof(gss_OID_desc)); ctx->oid->length = len; ctx->oid->elements = xmalloc(len); memcpy(ctx->oid->elements, data, len); } /* Set the contexts OID */ void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) { ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); } /* All this effort to report an error ... */ void ssh_gssapi_error(Gssctxt *ctxt) { char *s; s = ssh_gssapi_last_error(ctxt, NULL, NULL); debug("%s", s); free(s); } char * ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, OM_uint32 *minor_status) { OM_uint32 lmin; gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; OM_uint32 ctx; Buffer b; char *ret; buffer_init(&b); if (major_status != NULL) *major_status = ctxt->major; if (minor_status != NULL) *minor_status = ctxt->minor; ctx = 0; /* The GSSAPI error */ do { gss_display_status(&lmin, ctxt->major, GSS_C_GSS_CODE, ctxt->oid, &ctx, &msg); buffer_append(&b, msg.value, msg.length); buffer_put_char(&b, '\n'); gss_release_buffer(&lmin, &msg); } while (ctx != 0); /* The mechanism specific error */ do { gss_display_status(&lmin, ctxt->minor, GSS_C_MECH_CODE, ctxt->oid, &ctx, &msg); buffer_append(&b, msg.value, msg.length); buffer_put_char(&b, '\n'); gss_release_buffer(&lmin, &msg); } while (ctx != 0); buffer_put_char(&b, '\0'); ret = xmalloc(buffer_len(&b)); buffer_get(&b, ret, buffer_len(&b)); buffer_free(&b); return (ret); } /* * Initialise our GSSAPI context. We use this opaque structure to contain all * of the data which both the client and server need to persist across * {accept,init}_sec_context calls, so that when we do it from the userauth * stuff life is a little easier */ void ssh_gssapi_build_ctx(Gssctxt **ctx) { *ctx = xcalloc(1, sizeof (Gssctxt)); (*ctx)->context = GSS_C_NO_CONTEXT; (*ctx)->name = GSS_C_NO_NAME; (*ctx)->oid = GSS_C_NO_OID; (*ctx)->creds = GSS_C_NO_CREDENTIAL; (*ctx)->client = GSS_C_NO_NAME; (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; } /* Delete our context, providing it has been built correctly */ void ssh_gssapi_delete_ctx(Gssctxt **ctx) { OM_uint32 ms; if ((*ctx) == NULL) return; if ((*ctx)->context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); if ((*ctx)->name != GSS_C_NO_NAME) gss_release_name(&ms, &(*ctx)->name); if ((*ctx)->oid != GSS_C_NO_OID) { free((*ctx)->oid->elements); free((*ctx)->oid); (*ctx)->oid = GSS_C_NO_OID; } if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) gss_release_cred(&ms, &(*ctx)->creds); if ((*ctx)->client != GSS_C_NO_NAME) gss_release_name(&ms, &(*ctx)->client); if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) gss_release_cred(&ms, &(*ctx)->client_creds); free(*ctx); *ctx = NULL; } /* * Wrapper to init_sec_context * Requires that the context contains: * oid * server name (from ssh_gssapi_import_name) */ OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, gss_buffer_desc* send_tok, OM_uint32 *flags) { int deleg_flag = 0; if (deleg_creds) { deleg_flag = GSS_C_DELEG_FLAG; debug("Delegating credentials"); } ctx->major = gss_init_sec_context(&ctx->minor, GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx); return (ctx->major); } /* Create a service name for the given host */ OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host) { gss_buffer_desc gssbuf; char *val; xasprintf(&val, "host@%s", host); gssbuf.value = val; gssbuf.length = strlen(gssbuf.value); if ((ctx->major = gss_import_name(&ctx->minor, &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) ssh_gssapi_error(ctx); free(gssbuf.value); return (ctx->major); } OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); return (ctx->major); } void ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, const char *context) { buffer_init(b); buffer_put_string(b, session_id2, session_id2_len); buffer_put_char(b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(b, user); buffer_put_cstring(b, service); buffer_put_cstring(b, context); } int ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) { gss_buffer_desc token = GSS_C_EMPTY_BUFFER; OM_uint32 major, minor; gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && (memcmp(oid->elements, spnego_oid.elements, oid->length) == 0)) return 0; /* false */ ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); gss_release_buffer(&minor, &token); if ((*ctx)->context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor, &(*ctx)->context, GSS_C_NO_BUFFER); } if (GSS_ERROR(major)) ssh_gssapi_delete_ctx(ctx); return (!GSS_ERROR(major)); } #endif /* GSSAPI */ openssh-7.2p2/gss-serv-krb5.c010064400017500001750000000132161267006270000142330ustar00djmdjm/* $OpenBSD: gss-serv-krb5.c,v 1.8 2013/07/20 01:55:13 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #ifdef GSSAPI #ifdef KRB5 #include #include #include #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "log.h" #include "misc.h" #include "servconf.h" #include "buffer.h" #include "ssh-gss.h" extern ServerOptions options; #ifdef HEIMDAL # include #endif #ifdef HAVE_GSSAPI_KRB5_H # include #elif HAVE_GSSAPI_GSSAPI_KRB5_H # include #endif static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ static int ssh_gssapi_krb5_init(void) { krb5_error_code problem; if (krb_context != NULL) return 1; problem = krb5_init_context(&krb_context); if (problem) { logit("Cannot initialize krb5 context"); return 0; } return 1; } /* Check if this user is OK to login. This only works with krb5 - other * GSSAPI mechanisms will need their own. * Returns true if the user is OK to log in, otherwise returns 0 */ static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) { krb5_principal princ; int retval; const char *errmsg; if (ssh_gssapi_krb5_init() == 0) return 0; if ((retval = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { errmsg = krb5_get_error_message(krb_context, retval); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return 0; } if (krb5_kuserok(krb_context, princ, name)) { retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); } else retval = 0; krb5_free_principal(krb_context, princ); return retval; } /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; int len; const char *errmsg; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE if ((problem = krb5_cc_new_unique(krb_context, krb5_fcc_ops.prefix, NULL, &ccache)) != 0) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_new_unique(): %.100s", errmsg); # else if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { logit("krb5_cc_gen_new(): %.100s", krb5_get_err_text(krb_context, problem)); # endif krb5_free_error_message(krb_context, errmsg); return; } #else if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { errmsg = krb5_get_error_message(krb_context, problem); logit("ssh_krb5_cc_gen(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } #endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_initialize(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); client->store.envvar = "KRB5CCNAME"; len = strlen(client->store.filename) + 6; client->store.envval = xmalloc(len); snprintf(client->store.envval, len, "FILE:%s", client->store.filename); #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); return; } ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, NULL, &ssh_gssapi_krb5_storecreds }; #endif /* KRB5 */ #endif /* GSSAPI */ openssh-7.2p2/gss-serv.c010064400017500001750000000241751267006270000134000ustar00djmdjm/* $OpenBSD: gss-serv.c,v 1.29 2015/05/22 03:50:02 djm 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 #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "buffer.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "log.h" #include "channels.h" #include "session.h" #include "misc.h" #include "servconf.h" #include "ssh-gss.h" extern ServerOptions options; static ssh_gssapi_client gssapi_client = { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif ssh_gssapi_mech* supported_mechs[]= { #ifdef KRB5 &gssapi_kerberos_mech, #endif &gssapi_null_mech, }; /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. */ static gss_OID_set supported_oids; void ssh_gssapi_prepare_supported_oids(void) { ssh_gssapi_supported_oids(&supported_oids); } OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *ms, gss_OID member, int *present) { if (supported_oids == NULL) ssh_gssapi_prepare_supported_oids(); return gss_test_oid_set_member(ms, member, supported_oids, present); } /* * Acquire credentials for a server running on the current host. * Requires that the context structure contains a valid OID */ /* Returns a GSSAPI error code */ /* Privileged (called from ssh_gssapi_server_ctx) */ static OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx) { OM_uint32 status; char lname[NI_MAXHOST]; gss_OID_set oidset; if (options.gss_strict_acceptor) { gss_create_empty_oid_set(&status, &oidset); gss_add_oid_set_member(&status, ctx->oid, &oidset); if (gethostname(lname, MAXHOSTNAMELEN)) { gss_release_oid_set(&status, &oidset); return (-1); } if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { gss_release_oid_set(&status, &oidset); return (ctx->major); } if ((ctx->major = gss_acquire_cred(&ctx->minor, ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) ssh_gssapi_error(ctx); gss_release_oid_set(&status, &oidset); return (ctx->major); } else { ctx->name = GSS_C_NO_NAME; ctx->creds = GSS_C_NO_CREDENTIAL; } return GSS_S_COMPLETE; } /* Privileged */ OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { if (*ctx) ssh_gssapi_delete_ctx(ctx); ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); return (ssh_gssapi_acquire_cred(*ctx)); } /* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) { int i = 0; OM_uint32 min_status; int present; gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); gss_indicate_mechs(&min_status, &supported); while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, &supported_mechs[i]->oid, supported, &present))) present = 0; if (present) gss_add_oid_set_member(&min_status, &supported_mechs[i]->oid, oidset); i++; } gss_release_oid_set(&min_status, &supported); } /* Wrapper around accept_sec_context * Requires that the context contains: * oid * credentials (from ssh_gssapi_acquire_cred) */ /* Privileged */ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags) { OM_uint32 status; gss_OID mech; ctx->major = gss_accept_sec_context(&ctx->minor, &ctx->context, ctx->creds, recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech, send_tok, flags, NULL, &ctx->client_creds); if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx); if (ctx->client_creds) debug("Received some client credentials"); else debug("Got no client credentials"); status = ctx->major; /* Now, if we're complete and we have the right flags, then * we flag the user as also having been authenticated */ if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); } return (status); } /* * This parses an exported name, extracting the mechanism specific portion * to use for ACL checking. It verifies that the name belongs the mechanism * originally selected. */ static OM_uint32 ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) { u_char *tok; OM_uint32 offset; OM_uint32 oidl; tok = ename->value; /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct */ if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0) return GSS_S_FAILURE; /* * Extract the OID, and check it. Here GSSAPI breaks with tradition * and does use the OID type and length bytes. To confuse things * there are two lengths - the first including these, and the * second without. */ oidl = get_u16(tok+2); /* length including next two bytes */ oidl = oidl-2; /* turn it into the _real_ length of the variable OID */ /* * Check the BER encoding for correct type and length, that the * string is long enough and that the OID matches that in our context */ if (tok[4] != 0x06 || tok[5] != oidl || ename->length < oidl+6 || !ssh_gssapi_check_oid(ctx, tok+6, oidl)) return GSS_S_FAILURE; offset = oidl+6; if (ename->length < offset+4) return GSS_S_FAILURE; name->length = get_u32(tok+offset); offset += 4; if (UINT_MAX - offset < name->length) return GSS_S_FAILURE; if (ename->length < offset+name->length) return GSS_S_FAILURE; name->value = xmalloc(name->length+1); memcpy(name->value, tok+offset, name->length); ((char *)name->value)[name->length] = 0; return GSS_S_COMPLETE; } /* Extract the client details from a given context. This can only reliably * be called once for a context */ /* Privileged (called from accept_secure_ctx) */ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; gss_buffer_desc ename; client->mech = NULL; while (supported_mechs[i]->name != NULL) { if (supported_mechs[i]->oid.length == ctx->oid->length && (memcmp(supported_mechs[i]->oid.elements, ctx->oid->elements, ctx->oid->length) == 0)) client->mech = supported_mechs[i]; i++; } if (client->mech == NULL) return GSS_S_FAILURE; if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, &ename))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, &client->exportedname))) { return (ctx->major); } /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; return (ctx->major); } /* As user - called on fatal/exit */ void ssh_gssapi_cleanup_creds(void) { if (gssapi_client.store.filename != NULL) { /* Unlink probably isn't sufficient */ debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename); unlink(gssapi_client.store.filename); } } /* As user */ void ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); } /* This allows GSSAPI methods to do things to the childs environment based * on the passed authentication process and credentials. */ /* As user */ void ssh_gssapi_do_child(char ***envp, u_int *envsizep) { if (gssapi_client.store.envvar != NULL && gssapi_client.store.envval != NULL) { debug("Setting %s to %s", gssapi_client.store.envvar, gssapi_client.store.envval); child_set_env(envp, envsizep, gssapi_client.store.envvar, gssapi_client.store.envval); } } /* Privileged */ int ssh_gssapi_userok(char *user) { OM_uint32 lmin; if (gssapi_client.exportedname.length == 0 || gssapi_client.exportedname.value == NULL) { debug("No suitable client data"); return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) return 1; else { /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); explicit_bzero(&gssapi_client, sizeof(ssh_gssapi_client)); return 0; } else debug("ssh_gssapi_userok: Unknown GSSAPI mechanism"); return (0); } /* Privileged */ OM_uint32 ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) { ctx->major = gss_verify_mic(&ctx->minor, ctx->context, gssbuf, gssmic, NULL); return (ctx->major); } #endif openssh-7.2p2/hash.c010064400017500001750000000035121267006270000125420ustar00djmdjm/* $OpenBSD: hash.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* Copied from nacl-20110221/crypto_hash/sha512/ref/hash.c */ /* 20080913 D. J. Bernstein Public domain. */ #include "includes.h" #include "crypto_api.h" #define blocks crypto_hashblocks_sha512 static const unsigned char iv[64] = { 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 } ; typedef unsigned long long uint64; int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) { unsigned char h[64]; unsigned char padded[256]; unsigned int i; unsigned long long bytes = inlen; for (i = 0;i < 64;++i) h[i] = iv[i]; blocks(h,in,inlen); in += inlen; inlen &= 127; in -= inlen; for (i = 0;i < inlen;++i) padded[i] = in[i]; padded[inlen] = 0x80; if (inlen < 112) { for (i = inlen + 1;i < 119;++i) padded[i] = 0; padded[119] = bytes >> 61; padded[120] = bytes >> 53; padded[121] = bytes >> 45; padded[122] = bytes >> 37; padded[123] = bytes >> 29; padded[124] = bytes >> 21; padded[125] = bytes >> 13; padded[126] = bytes >> 5; padded[127] = bytes << 3; blocks(h,padded,128); } else { for (i = inlen + 1;i < 247;++i) padded[i] = 0; padded[247] = bytes >> 61; padded[248] = bytes >> 53; padded[249] = bytes >> 45; padded[250] = bytes >> 37; padded[251] = bytes >> 29; padded[252] = bytes >> 21; padded[253] = bytes >> 13; padded[254] = bytes >> 5; padded[255] = bytes << 3; blocks(h,padded,256); } for (i = 0;i < 64;++i) out[i] = h[i]; return 0; } openssh-7.2p2/hmac.c010064400017500001750000000121201267006270000125220ustar00djmdjm/* $OpenBSD: hmac.c,v 1.12 2015/03/24 20:03:44 markus Exp $ */ /* * Copyright (c) 2014 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #include #include "sshbuf.h" #include "digest.h" #include "hmac.h" struct ssh_hmac_ctx { int alg; struct ssh_digest_ctx *ictx; struct ssh_digest_ctx *octx; struct ssh_digest_ctx *digest; u_char *buf; size_t buf_len; }; size_t ssh_hmac_bytes(int alg) { return ssh_digest_bytes(alg); } struct ssh_hmac_ctx * ssh_hmac_start(int alg) { struct ssh_hmac_ctx *ret; if ((ret = calloc(1, sizeof(*ret))) == NULL) return NULL; ret->alg = alg; if ((ret->ictx = ssh_digest_start(alg)) == NULL || (ret->octx = ssh_digest_start(alg)) == NULL || (ret->digest = ssh_digest_start(alg)) == NULL) goto fail; ret->buf_len = ssh_digest_blocksize(ret->ictx); if ((ret->buf = calloc(1, ret->buf_len)) == NULL) goto fail; return ret; fail: ssh_hmac_free(ret); return NULL; } int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) { size_t i; /* reset ictx and octx if no is key given */ if (key != NULL) { /* truncate long keys */ if (klen <= ctx->buf_len) memcpy(ctx->buf, key, klen); else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf, ctx->buf_len) < 0) return -1; for (i = 0; i < ctx->buf_len; i++) ctx->buf[i] ^= 0x36; if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0) return -1; for (i = 0; i < ctx->buf_len; i++) ctx->buf[i] ^= 0x36 ^ 0x5c; if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0) return -1; explicit_bzero(ctx->buf, ctx->buf_len); } /* start with ictx */ if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0) return -1; return 0; } int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) { return ssh_digest_update(ctx->digest, m, mlen); } int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const struct sshbuf *b) { return ssh_digest_update_buffer(ctx->digest, b); } int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) { size_t len; len = ssh_digest_bytes(ctx->alg); if (dlen < len || ssh_digest_final(ctx->digest, ctx->buf, len)) return -1; /* switch to octx */ if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 || ssh_digest_update(ctx->digest, ctx->buf, len) < 0 || ssh_digest_final(ctx->digest, d, dlen) < 0) return -1; return 0; } void ssh_hmac_free(struct ssh_hmac_ctx *ctx) { if (ctx != NULL) { ssh_digest_free(ctx->ictx); ssh_digest_free(ctx->octx); ssh_digest_free(ctx->digest); if (ctx->buf) { explicit_bzero(ctx->buf, ctx->buf_len); free(ctx->buf); } explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } } #ifdef TEST /* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */ static void hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen) { struct ssh_hmac_ctx *ctx; size_t i; u_char digest[16]; if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL) printf("ssh_hmac_start failed"); if (ssh_hmac_init(ctx, key, klen) < 0 || ssh_hmac_update(ctx, m, mlen) < 0 || ssh_hmac_final(ctx, digest, sizeof(digest)) < 0) printf("ssh_hmac_xxx failed"); ssh_hmac_free(ctx); if (memcmp(e, digest, elen)) { for (i = 0; i < elen; i++) printf("[%zu] %2.2x %2.2x\n", i, e[i], digest[i]); printf("mismatch\n"); } else printf("ok\n"); } int main(int argc, char **argv) { /* try test vectors from RFC 2104 */ u_char key1[16] = { 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb }; u_char *data1 = "Hi There"; u_char dig1[16] = { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }; u_char *key2 = "Jefe"; u_char *data2 = "what do ya want for nothing?"; u_char dig2[16] = { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }; u_char key3[16]; u_char data3[50]; u_char dig3[16] = { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }; memset(key3, 0xaa, sizeof(key3)); memset(data3, 0xdd, sizeof(data3)); hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1)); hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2)); hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3)); return 0; } #endif openssh-7.2p2/hmac.h010064400017500001750000000031761267006270000125420ustar00djmdjm/* $OpenBSD: hmac.h,v 1.9 2014/06/24 01:13:21 djm Exp $ */ /* * Copyright (c) 2014 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _HMAC_H #define _HMAC_H /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ size_t ssh_hmac_bytes(int alg); struct sshbuf; struct ssh_hmac_ctx; struct ssh_hmac_ctx *ssh_hmac_start(int alg); /* Sets the state of the HMAC or resets the state if key == NULL */ int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) __attribute__((__bounded__(__buffer__, 2, 3))); int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) __attribute__((__bounded__(__buffer__, 2, 3))); int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const struct sshbuf *b); int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) __attribute__((__bounded__(__buffer__, 2, 3))); void ssh_hmac_free(struct ssh_hmac_ctx *ctx); #endif /* _HMAC_H */ openssh-7.2p2/hostfile.c010064400017500001750000000544361267006270000134470ustar00djmdjm/* $OpenBSD: hostfile.c,v 1.66 2015/05/04 06:10:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for manipulating the known hosts files. * * 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 Markus Friedl. All rights reserved. * Copyright (c) 1999 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 #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "match.h" #include "sshkey.h" #include "hostfile.h" #include "log.h" #include "misc.h" #include "ssherr.h" #include "digest.h" #include "hmac.h" struct hostkeys { struct hostkey_entry *entries; u_int num_entries; }; /* XXX hmac is too easy to dictionary attack; use bcrypt? */ static int extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) { char *p, *b64salt; u_int b64len; int ret; if (l < sizeof(HASH_MAGIC) - 1) { debug2("extract_salt: string too short"); return (-1); } if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) { debug2("extract_salt: invalid magic identifier"); return (-1); } s += sizeof(HASH_MAGIC) - 1; l -= sizeof(HASH_MAGIC) - 1; if ((p = memchr(s, HASH_DELIM, l)) == NULL) { debug2("extract_salt: missing salt termination character"); return (-1); } b64len = p - s; /* Sanity check */ if (b64len == 0 || b64len > 1024) { debug2("extract_salt: bad encoded salt length %u", b64len); return (-1); } b64salt = xmalloc(1 + b64len); memcpy(b64salt, s, b64len); b64salt[b64len] = '\0'; ret = __b64_pton(b64salt, salt, salt_len); free(b64salt); if (ret == -1) { debug2("extract_salt: salt decode error"); return (-1); } if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) { debug2("extract_salt: expected salt len %zd, got %d", ssh_hmac_bytes(SSH_DIGEST_SHA1), ret); return (-1); } return (0); } char * host_hash(const char *host, const char *name_from_hostfile, u_int src_len) { struct ssh_hmac_ctx *ctx; u_char salt[256], result[256]; char uu_salt[512], uu_result[512]; static char encoded[1024]; u_int i, len; len = ssh_digest_bytes(SSH_DIGEST_SHA1); if (name_from_hostfile == NULL) { /* Create new salt */ for (i = 0; i < len; i++) salt[i] = arc4random(); } else { /* Extract salt from known host entry */ if (extract_salt(name_from_hostfile, src_len, salt, sizeof(salt)) == -1) return (NULL); } if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL || ssh_hmac_init(ctx, salt, len) < 0 || ssh_hmac_update(ctx, host, strlen(host)) < 0 || ssh_hmac_final(ctx, result, sizeof(result))) fatal("%s: ssh_hmac failed", __func__); ssh_hmac_free(ctx); if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) fatal("%s: __b64_ntop failed", __func__); snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, HASH_DELIM, uu_result); return (encoded); } /* * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the * pointer over the key. Skips any whitespace at the beginning and at end. */ int hostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret) { char *cp; int r; /* Skip leading whitespace. */ for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) ; if ((r = sshkey_read(ret, &cp)) != 0) return 0; /* Skip trailing whitespace. */ for (; *cp == ' ' || *cp == '\t'; cp++) ; /* Return results. */ *cpp = cp; if (bitsp != NULL) *bitsp = sshkey_size(ret); return 1; } static HostkeyMarker check_markers(char **cpp) { char marker[32], *sp, *cp = *cpp; int ret = MRK_NONE; while (*cp == '@') { /* Only one marker is allowed */ if (ret != MRK_NONE) return MRK_ERROR; /* Markers are terminated by whitespace */ if ((sp = strchr(cp, ' ')) == NULL && (sp = strchr(cp, '\t')) == NULL) return MRK_ERROR; /* Extract marker for comparison */ if (sp <= cp + 1 || sp >= cp + sizeof(marker)) return MRK_ERROR; memcpy(marker, cp, sp - cp); marker[sp - cp] = '\0'; if (strcmp(marker, CA_MARKER) == 0) ret = MRK_CA; else if (strcmp(marker, REVOKE_MARKER) == 0) ret = MRK_REVOKE; else return MRK_ERROR; /* Skip past marker and any whitespace that follows it */ cp = sp; for (; *cp == ' ' || *cp == '\t'; cp++) ; } *cpp = cp; return ret; } struct hostkeys * init_hostkeys(void) { struct hostkeys *ret = xcalloc(1, sizeof(*ret)); ret->entries = NULL; return ret; } struct load_callback_ctx { const char *host; u_long num_loaded; struct hostkeys *hostkeys; }; static int record_hostkey(struct hostkey_foreach_line *l, void *_ctx) { struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx; struct hostkeys *hostkeys = ctx->hostkeys; struct hostkey_entry *tmp; if (l->status == HKF_STATUS_INVALID) { /* XXX make this verbose() in the future */ debug("%s:%ld: parse error in hostkeys file", l->path, l->linenum); return 0; } debug3("%s: found %skey type %s in file %s:%lu", __func__, l->marker == MRK_NONE ? "" : (l->marker == MRK_CA ? "ca " : "revoked "), sshkey_type(l->key), l->path, l->linenum); if ((tmp = reallocarray(hostkeys->entries, hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL) return SSH_ERR_ALLOC_FAIL; hostkeys->entries = tmp; hostkeys->entries[hostkeys->num_entries].host = xstrdup(ctx->host); hostkeys->entries[hostkeys->num_entries].file = xstrdup(l->path); hostkeys->entries[hostkeys->num_entries].line = l->linenum; hostkeys->entries[hostkeys->num_entries].key = l->key; l->key = NULL; /* steal it */ hostkeys->entries[hostkeys->num_entries].marker = l->marker; hostkeys->num_entries++; ctx->num_loaded++; return 0; } void load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) { int r; struct load_callback_ctx ctx; ctx.host = host; ctx.num_loaded = 0; ctx.hostkeys = hostkeys; if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL, HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) { if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) debug("%s: hostkeys_foreach failed for %s: %s", __func__, path, ssh_err(r)); } if (ctx.num_loaded != 0) debug3("%s: loaded %lu keys from %s", __func__, ctx.num_loaded, host); } void free_hostkeys(struct hostkeys *hostkeys) { u_int i; for (i = 0; i < hostkeys->num_entries; i++) { free(hostkeys->entries[i].host); free(hostkeys->entries[i].file); sshkey_free(hostkeys->entries[i].key); explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); } free(hostkeys->entries); explicit_bzero(hostkeys, sizeof(*hostkeys)); free(hostkeys); } static int check_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k) { int is_cert = sshkey_is_cert(k); u_int i; for (i = 0; i < hostkeys->num_entries; i++) { if (hostkeys->entries[i].marker != MRK_REVOKE) continue; if (sshkey_equal_public(k, hostkeys->entries[i].key)) return -1; if (is_cert && sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) return -1; } return 0; } /* * Match keys against a specified key, or look one up by key type. * * If looking for a keytype (key == NULL) and one is found then return * HOST_FOUND, otherwise HOST_NEW. * * If looking for a key (key != NULL): * 1. If the key is a cert and a matching CA is found, return HOST_OK * 2. If the key is not a cert and a matching key is found, return HOST_OK * 3. If no key matches but a key with a different type is found, then * return HOST_CHANGED * 4. If no matching keys are found, then return HOST_NEW. * * Finally, check any found key is not revoked. */ static HostStatus check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, struct sshkey *k, int keytype, const struct hostkey_entry **found) { u_int i; HostStatus end_return = HOST_NEW; int want_cert = sshkey_is_cert(k); HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2; if (found != NULL) *found = NULL; for (i = 0; i < hostkeys->num_entries; i++) { if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1) continue; if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1) continue; if (hostkeys->entries[i].marker != want_marker) continue; if (k == NULL) { if (hostkeys->entries[i].key->type != keytype) continue; end_return = HOST_FOUND; if (found != NULL) *found = hostkeys->entries + i; k = hostkeys->entries[i].key; break; } if (want_cert) { if (sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) { /* A matching CA exists */ end_return = HOST_OK; if (found != NULL) *found = hostkeys->entries + i; break; } } else { if (sshkey_equal(k, hostkeys->entries[i].key)) { end_return = HOST_OK; if (found != NULL) *found = hostkeys->entries + i; break; } /* A non-maching key exists */ end_return = HOST_CHANGED; if (found != NULL) *found = hostkeys->entries + i; } } if (check_key_not_revoked(hostkeys, k) != 0) { end_return = HOST_REVOKED; if (found != NULL) *found = NULL; } return end_return; } HostStatus check_key_in_hostkeys(struct hostkeys *hostkeys, struct sshkey *key, const struct hostkey_entry **found) { if (key == NULL) fatal("no key to look up"); return check_hostkeys_by_key_or_type(hostkeys, key, 0, found); } int lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, const struct hostkey_entry **found) { return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype, found) == HOST_FOUND); } static int write_host_entry(FILE *f, const char *host, const char *ip, const struct sshkey *key, int store_hash) { int r, success = 0; char *hashed_host = NULL; if (store_hash) { if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { error("%s: host_hash failed", __func__); return 0; } fprintf(f, "%s ", hashed_host); } else if (ip != NULL) fprintf(f, "%s,%s ", host, ip); else fprintf(f, "%s ", host); if ((r = sshkey_write(key, f)) == 0) success = 1; else error("%s: sshkey_write failed: %s", __func__, ssh_err(r)); fputc('\n', f); return success; } /* * Appends an entry to the host file. Returns false if the entry could not * be appended. */ int add_host_to_hostfile(const char *filename, const char *host, const struct sshkey *key, int store_hash) { FILE *f; int success; if (key == NULL) return 1; /* XXX ? */ f = fopen(filename, "a"); if (!f) return 0; success = write_host_entry(f, host, NULL, key, store_hash); fclose(f); return success; } struct host_delete_ctx { FILE *out; int quiet; const char *host; int *skip_keys; /* XXX split for host/ip? might want to ensure both */ struct sshkey * const *keys; size_t nkeys; int modified; }; static int host_delete(struct hostkey_foreach_line *l, void *_ctx) { struct host_delete_ctx *ctx = (struct host_delete_ctx *)_ctx; int loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; size_t i; if (l->status == HKF_STATUS_MATCHED) { if (l->marker != MRK_NONE) { /* Don't remove CA and revocation lines */ fprintf(ctx->out, "%s\n", l->line); return 0; } /* XXX might need a knob for this later */ /* Don't remove RSA1 keys */ if (l->key->type == KEY_RSA1) { fprintf(ctx->out, "%s\n", l->line); return 0; } /* * If this line contains one of the keys that we will be * adding later, then don't change it and mark the key for * skipping. */ for (i = 0; i < ctx->nkeys; i++) { if (sshkey_equal(ctx->keys[i], l->key)) { ctx->skip_keys[i] = 1; fprintf(ctx->out, "%s\n", l->line); debug3("%s: %s key already at %s:%ld", __func__, sshkey_type(l->key), l->path, l->linenum); return 0; } } /* * Hostname matches and has no CA/revoke marker, delete it * by *not* writing the line to ctx->out. */ do_log2(loglevel, "%s%s%s:%ld: Removed %s key for host %s", ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "", l->path, l->linenum, sshkey_type(l->key), ctx->host); ctx->modified = 1; return 0; } /* Retain non-matching hosts and invalid lines when deleting */ if (l->status == HKF_STATUS_INVALID) { do_log2(loglevel, "%s%s%s:%ld: invalid known_hosts entry", ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "", l->path, l->linenum); } fprintf(ctx->out, "%s\n", l->line); return 0; } int hostfile_replace_entries(const char *filename, const char *host, const char *ip, struct sshkey **keys, size_t nkeys, int store_hash, int quiet, int hash_alg) { int r, fd, oerrno = 0; int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; struct host_delete_ctx ctx; char *fp, *temp = NULL, *back = NULL; mode_t omask; size_t i; omask = umask(077); memset(&ctx, 0, sizeof(ctx)); ctx.host = host; ctx.quiet = quiet; if ((ctx.skip_keys = calloc(nkeys, sizeof(*ctx.skip_keys))) == NULL) return SSH_ERR_ALLOC_FAIL; ctx.keys = keys; ctx.nkeys = nkeys; ctx.modified = 0; /* * Prepare temporary file for in-place deletion. */ if ((r = asprintf(&temp, "%s.XXXXXXXXXXX", filename)) < 0 || (r = asprintf(&back, "%s.old", filename)) < 0) { r = SSH_ERR_ALLOC_FAIL; goto fail; } if ((fd = mkstemp(temp)) == -1) { oerrno = errno; error("%s: mkstemp: %s", __func__, strerror(oerrno)); r = SSH_ERR_SYSTEM_ERROR; goto fail; } if ((ctx.out = fdopen(fd, "w")) == NULL) { oerrno = errno; close(fd); error("%s: fdopen: %s", __func__, strerror(oerrno)); r = SSH_ERR_SYSTEM_ERROR; goto fail; } /* Remove all entries for the specified host from the file */ if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip, HKF_WANT_PARSE_KEY)) != 0) { error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); goto fail; } /* Add the requested keys */ for (i = 0; i < nkeys; i++) { if (ctx.skip_keys[i]) continue; if ((fp = sshkey_fingerprint(keys[i], hash_alg, SSH_FP_DEFAULT)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto fail; } do_log2(loglevel, "%s%sAdding new key for %s to %s: %s %s", quiet ? __func__ : "", quiet ? ": " : "", host, filename, sshkey_ssh_name(keys[i]), fp); free(fp); if (!write_host_entry(ctx.out, host, ip, keys[i], store_hash)) { r = SSH_ERR_INTERNAL_ERROR; goto fail; } ctx.modified = 1; } fclose(ctx.out); ctx.out = NULL; if (ctx.modified) { /* Backup the original file and replace it with the temporary */ if (unlink(back) == -1 && errno != ENOENT) { oerrno = errno; error("%s: unlink %.100s: %s", __func__, back, strerror(errno)); r = SSH_ERR_SYSTEM_ERROR; goto fail; } if (link(filename, back) == -1) { oerrno = errno; error("%s: link %.100s to %.100s: %s", __func__, filename, back, strerror(errno)); r = SSH_ERR_SYSTEM_ERROR; goto fail; } if (rename(temp, filename) == -1) { oerrno = errno; error("%s: rename \"%s\" to \"%s\": %s", __func__, temp, filename, strerror(errno)); r = SSH_ERR_SYSTEM_ERROR; goto fail; } } else { /* No changes made; just delete the temporary file */ if (unlink(temp) != 0) error("%s: unlink \"%s\": %s", __func__, temp, strerror(errno)); } /* success */ r = 0; fail: if (temp != NULL && r != 0) unlink(temp); free(temp); free(back); if (ctx.out != NULL) fclose(ctx.out); free(ctx.skip_keys); umask(omask); if (r == SSH_ERR_SYSTEM_ERROR) errno = oerrno; return r; } static int match_maybe_hashed(const char *host, const char *names, int *was_hashed) { int hashed = *names == HASH_DELIM; const char *hashed_host; size_t nlen = strlen(names); if (was_hashed != NULL) *was_hashed = hashed; if (hashed) { if ((hashed_host = host_hash(host, names, nlen)) == NULL) return -1; return nlen == strlen(hashed_host) && strncmp(hashed_host, names, nlen) == 0; } return match_hostname(host, names) == 1; } int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, const char *host, const char *ip, u_int options) { FILE *f; char line[8192], oline[8192], ktype[128]; u_long linenum = 0; char *cp, *cp2; u_int kbits; int hashed; int s, r = 0; struct hostkey_foreach_line lineinfo; size_t l; memset(&lineinfo, 0, sizeof(lineinfo)); if (host == NULL && (options & HKF_WANT_MATCH) != 0) return SSH_ERR_INVALID_ARGUMENT; if ((f = fopen(path, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; debug3("%s: reading file \"%s\"", __func__, path); while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { line[strcspn(line, "\n")] = '\0'; strlcpy(oline, line, sizeof(oline)); sshkey_free(lineinfo.key); memset(&lineinfo, 0, sizeof(lineinfo)); lineinfo.path = path; lineinfo.linenum = linenum; lineinfo.line = oline; lineinfo.marker = MRK_NONE; lineinfo.status = HKF_STATUS_OK; lineinfo.keytype = KEY_UNSPEC; /* Skip any leading whitespace, comments and empty lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; if (!*cp || *cp == '#' || *cp == '\n') { if ((options & HKF_WANT_MATCH) == 0) { lineinfo.status = HKF_STATUS_COMMENT; if ((r = callback(&lineinfo, ctx)) != 0) break; } continue; } if ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) { verbose("%s: invalid marker at %s:%lu", __func__, path, linenum); if ((options & HKF_WANT_MATCH) == 0) goto bad; continue; } /* Find the end of the host name portion. */ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) ; lineinfo.hosts = cp; *cp2++ = '\0'; /* Check if the host name matches. */ if (host != NULL) { if ((s = match_maybe_hashed(host, lineinfo.hosts, &hashed)) == -1) { debug2("%s: %s:%ld: bad host hash \"%.32s\"", __func__, path, linenum, lineinfo.hosts); goto bad; } if (s == 1) { lineinfo.status = HKF_STATUS_MATCHED; lineinfo.match |= HKF_MATCH_HOST | (hashed ? HKF_MATCH_HOST_HASHED : 0); } /* Try matching IP address if supplied */ if (ip != NULL) { if ((s = match_maybe_hashed(ip, lineinfo.hosts, &hashed)) == -1) { debug2("%s: %s:%ld: bad ip hash " "\"%.32s\"", __func__, path, linenum, lineinfo.hosts); goto bad; } if (s == 1) { lineinfo.status = HKF_STATUS_MATCHED; lineinfo.match |= HKF_MATCH_IP | (hashed ? HKF_MATCH_IP_HASHED : 0); } } /* * Skip this line if host matching requested and * neither host nor address matched. */ if ((options & HKF_WANT_MATCH) != 0 && lineinfo.status != HKF_STATUS_MATCHED) continue; } /* Got a match. Skip host name and any following whitespace */ for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) ; if (*cp2 == '\0' || *cp2 == '#') { debug2("%s:%ld: truncated before key type", path, linenum); goto bad; } lineinfo.rawkey = cp = cp2; if ((options & HKF_WANT_PARSE_KEY) != 0) { /* * Extract the key from the line. This will skip * any leading whitespace. Ignore badly formatted * lines. */ if ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) { error("%s: sshkey_new failed", __func__); r = SSH_ERR_ALLOC_FAIL; break; } if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) { #ifdef WITH_SSH1 sshkey_free(lineinfo.key); lineinfo.key = sshkey_new(KEY_RSA1); if (lineinfo.key == NULL) { error("%s: sshkey_new fail", __func__); r = SSH_ERR_ALLOC_FAIL; break; } if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) goto bad; #else goto bad; #endif } lineinfo.keytype = lineinfo.key->type; lineinfo.comment = cp; } else { /* Extract and parse key type */ l = strcspn(lineinfo.rawkey, " \t"); if (l <= 1 || l >= sizeof(ktype) || lineinfo.rawkey[l] == '\0') goto bad; memcpy(ktype, lineinfo.rawkey, l); ktype[l] = '\0'; lineinfo.keytype = sshkey_type_from_name(ktype); /* * Assume RSA1 if the first component is a short * decimal number. */ if (lineinfo.keytype == KEY_UNSPEC && l < 8 && strspn(ktype, "0123456789") == l) lineinfo.keytype = KEY_RSA1; /* * Check that something other than whitespace follows * the key type. This won't catch all corruption, but * it does catch trivial truncation. */ cp2 += l; /* Skip past key type */ for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) ; if (*cp2 == '\0' || *cp2 == '#') { debug2("%s:%ld: truncated after key type", path, linenum); lineinfo.keytype = KEY_UNSPEC; } if (lineinfo.keytype == KEY_UNSPEC) { bad: sshkey_free(lineinfo.key); lineinfo.key = NULL; lineinfo.status = HKF_STATUS_INVALID; if ((r = callback(&lineinfo, ctx)) != 0) break; continue; } } if ((r = callback(&lineinfo, ctx)) != 0) break; } sshkey_free(lineinfo.key); fclose(f); return r; } openssh-7.2p2/hostfile.h010064400017500001750000000074661267006270000134550ustar00djmdjm/* $OpenBSD: hostfile.h,v 1.24 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 HOSTFILE_H #define HOSTFILE_H typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND } HostStatus; typedef enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA } HostkeyMarker; struct hostkey_entry { char *host; char *file; u_long line; struct sshkey *key; HostkeyMarker marker; }; struct hostkeys; struct hostkeys *init_hostkeys(void); void load_hostkeys(struct hostkeys *, const char *, const char *); void free_hostkeys(struct hostkeys *); HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *, const struct hostkey_entry **); int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, const struct hostkey_entry **); int hostfile_read_key(char **, u_int *, struct sshkey *); int add_host_to_hostfile(const char *, const char *, const struct sshkey *, int); int hostfile_replace_entries(const char *filename, const char *host, const char *ip, struct sshkey **keys, size_t nkeys, int store_hash, int quiet, int hash_alg); #define HASH_MAGIC "|1|" #define HASH_DELIM '|' #define CA_MARKER "@cert-authority" #define REVOKE_MARKER "@revoked" char *host_hash(const char *, const char *, u_int); /* * Iterate through a hostkeys file, optionally parsing keys and matching * hostnames. Allows access to the raw keyfile lines to allow * streaming edits to the file to take place. */ #define HKF_WANT_MATCH (1) /* return only matching hosts/addrs */ #define HKF_WANT_PARSE_KEY (1<<1) /* need key parsed */ #define HKF_STATUS_OK 0 /* Line parsed, didn't match host */ #define HKF_STATUS_INVALID 1 /* line had parse error */ #define HKF_STATUS_COMMENT 2 /* valid line contained no key */ #define HKF_STATUS_MATCHED 3 /* hostname or IP matched */ #define HKF_MATCH_HOST (1) /* hostname matched */ #define HKF_MATCH_IP (1<<1) /* address matched */ #define HKF_MATCH_HOST_HASHED (1<<2) /* hostname was hashed */ #define HKF_MATCH_IP_HASHED (1<<3) /* address was hashed */ /* XXX HKF_MATCH_KEY_TYPE? */ /* * The callback function receives this as an argument for each matching * hostkey line. The callback may "steal" the 'key' field by setting it to NULL. * If a parse error occurred, then "hosts" and subsequent options may be NULL. */ struct hostkey_foreach_line { const char *path; /* Path of file */ u_long linenum; /* Line number */ u_int status; /* One of HKF_STATUS_* */ u_int match; /* Zero or more of HKF_MATCH_* OR'd together */ char *line; /* Entire key line; mutable by callback */ int marker; /* CA/revocation markers; indicated by MRK_* value */ const char *hosts; /* Raw hosts text, may be hashed or list multiple */ const char *rawkey; /* Text of key and any comment following it */ int keytype; /* Type of key; KEY_UNSPEC for invalid/comment lines */ struct sshkey *key; /* Key, if parsed ok and HKF_WANT_MATCH_HOST set */ const char *comment; /* Any comment following the key */ }; /* * Callback fires for each line (or matching line if a HKF_WANT_* option * is set). The foreach loop will terminate if the callback returns a non- * zero exit status. */ typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx); /* Iterate over a hostkeys file */ int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, const char *host, const char *ip, u_int options); #endif openssh-7.2p2/includes.h010064400017500001750000000074231267006270000134370ustar00djmdjm/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * This file includes most of the needed system headers. * * 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 INCLUDES_H #define INCLUDES_H #include "config.h" #ifndef _GNU_SOURCE #define _GNU_SOURCE /* activate extra prototypes for glibc */ #endif #include #include #include /* For CMSG_* */ #ifdef HAVE_LIMITS_H # include /* For PATH_MAX, _POSIX_HOST_NAME_MAX */ #endif #ifdef HAVE_BSTRING_H # include #endif #ifdef HAVE_ENDIAN_H # include #endif #ifdef HAVE_TTYENT_H # include #endif #ifdef HAVE_UTIME_H # include #endif #ifdef HAVE_MAILLOCK_H # include /* For _PATH_MAILDIR */ #endif #ifdef HAVE_NEXT # include #endif #ifdef HAVE_PATHS_H # include #endif /* *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively */ #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_LOGIN_H # include #endif #ifdef HAVE_UTMP_H # include #endif #ifdef HAVE_UTMPX_H # include #endif #ifdef HAVE_LASTLOG_H # include #endif #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_BSDTTY_H # include #endif #ifdef HAVE_STDINT_H # include #endif #include #ifdef HAVE_SYS_BITYPES_H # include /* For u_intXX_t */ #endif #ifdef HAVE_SYS_CDEFS_H # include /* For __P() */ #endif #ifdef HAVE_SYS_STAT_H # include /* For S_* constants and macros */ #endif #ifdef HAVE_SYS_SYSMACROS_H # include /* For MIN, MAX, etc */ #endif #ifdef HAVE_SYS_MMAN_H #include /* for MAP_ANONYMOUS */ #endif #ifdef HAVE_SYS_STRTIO_H #include /* for TIOCCBRK on HP-UX */ #endif #if defined(HAVE_SYS_PTMS_H) && defined(HAVE_DEV_PTMX) # if defined(HAVE_SYS_STREAM_H) # include /* reqd for queue_t on Solaris 2.5.1 */ # endif #include /* for grantpt() and friends */ #endif #include #include /* For typedefs */ #ifdef HAVE_RPC_TYPES_H # include /* For INADDR_LOOPBACK */ #endif #ifdef USE_PAM #if defined(HAVE_SECURITY_PAM_APPL_H) # include #elif defined (HAVE_PAM_PAM_APPL_H) # include #endif #endif #ifdef HAVE_READPASSPHRASE_H # include #endif #ifdef HAVE_IA_H # include #endif #ifdef HAVE_IAF_H # include #endif #ifdef HAVE_TMPDIR_H # include #endif #if defined(HAVE_BSD_LIBUTIL_H) # include #elif defined(HAVE_LIBUTIL_H) # include #endif #if defined(KRB5) && defined(USE_AFS) # include # include #endif #if defined(HAVE_SYS_SYSLOG_H) # include #endif #include /* * On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here. */ #ifdef GETSPNAM_CONFLICTING_DEFS # ifdef _INCLUDE__STDC__ # undef _INCLUDE__STDC__ # endif #endif #ifdef WITH_OPENSSL #include /* For OPENSSL_VERSION_NUMBER */ #endif #include "defines.h" #include "platform.h" #include "openbsd-compat/openbsd-compat.h" #include "openbsd-compat/bsd-nextstep.h" #include "entropy.h" #endif /* INCLUDES_H */ openssh-7.2p2/install-sh010075500017500001750000000127221267006270000134620ustar00djmdjm#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 openssh-7.2p2/kex.c010064400017500001750000000621531267006270000124140ustar00djmdjm/* $OpenBSD: kex.c,v 1.117 2016/02/08 10:57:07 djm Exp $ */ /* * Copyright (c) 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. */ #include "includes.h" #include /* MAX roundup */ #include #include #include #include #include #ifdef WITH_OPENSSL #include #endif #include "ssh2.h" #include "packet.h" #include "compat.h" #include "cipher.h" #include "sshkey.h" #include "kex.h" #include "log.h" #include "mac.h" #include "match.h" #include "misc.h" #include "dispatch.h" #include "monitor.h" #include "ssherr.h" #include "sshbuf.h" #include "digest.h" #if OPENSSL_VERSION_NUMBER >= 0x00907000L # if defined(HAVE_EVP_SHA256) # define evp_ssh_sha256 EVP_sha256 # else extern const EVP_MD *evp_ssh_sha256(void); # endif #endif /* prototype */ static int kex_choose_conf(struct ssh *); static int kex_input_newkeys(int, u_int32_t, void *); static const char *proposal_names[PROPOSAL_MAX] = { "KEX algorithms", "host key algorithms", "ciphers ctos", "ciphers stoc", "MACs ctos", "MACs stoc", "compression ctos", "compression stoc", "languages ctos", "languages stoc", }; struct kexalg { char *name; u_int type; int ec_nid; int hash_alg; }; static const struct kexalg kexalgs[] = { #ifdef WITH_OPENSSL { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, #ifdef HAVE_EVP_SHA256 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 */ #ifdef OPENSSL_HAS_ECC { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, SSH_DIGEST_SHA384 }, # ifdef OPENSSL_HAS_NISTP521 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, SSH_DIGEST_SHA512 }, # endif /* OPENSSL_HAS_NISTP521 */ #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, -1, -1, -1}, }; char * kex_alg_list(char sep) { char *ret = NULL, *tmp; size_t nlen, rlen = 0; const struct kexalg *k; for (k = kexalgs; k->name != NULL; k++) { if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { free(ret); return NULL; } ret = tmp; memcpy(ret + rlen, k->name, nlen + 1); rlen += nlen; } return ret; } static const struct kexalg * kex_alg_by_name(const char *name) { const struct kexalg *k; for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; } return NULL; } /* Validate KEX method name list */ int kex_names_valid(const char *names) { char *s, *cp, *p; if (names == NULL || strcmp(names, "") == 0) return 0; if ((s = cp = strdup(names)) == NULL) return 0; for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { error("Unsupported KEX algorithm \"%.100s\"", p); free(s); return 0; } } debug3("kex names ok: [%s]", names); free(s); return 1; } /* * Concatenate algorithm names, avoiding duplicates in the process. * Caller must free returned string. */ char * kex_names_cat(const char *a, const char *b) { char *ret = NULL, *tmp = NULL, *cp, *p; size_t len; if (a == NULL || *a == '\0') return NULL; if (b == NULL || *b == '\0') return strdup(a); if (strlen(b) > 1024*1024) return NULL; len = strlen(a) + strlen(b) + 2; if ((tmp = cp = strdup(b)) == NULL || (ret = calloc(1, len)) == NULL) { free(tmp); return NULL; } strlcpy(ret, a, len); for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (match_list(ret, p, NULL) != NULL) continue; /* Algorithm already present */ if (strlcat(ret, ",", len) >= len || strlcat(ret, p, len) >= len) { free(tmp); free(ret); return NULL; /* Shouldn't happen */ } } free(tmp); return ret; } /* * Assemble a list of algorithms from a default list and a string from a * configuration file. The user-provided string may begin with '+' to * indicate that it should be appended to the default. */ int kex_assemble_names(const char *def, char **list) { char *ret; if (list == NULL || *list == NULL || **list == '\0') { *list = strdup(def); return 0; } if (**list != '+') { return 0; } if ((ret = kex_names_cat(def, *list + 1)) == NULL) return SSH_ERR_ALLOC_FAIL; free(*list); *list = ret; return 0; } /* put algorithm proposal into buffer */ int kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) { u_int i; int r; sshbuf_reset(b); /* * add a dummy cookie, the cookie will be overwritten by * kex_send_kexinit(), each time a kexinit is set */ for (i = 0; i < KEX_COOKIE_LEN; i++) { if ((r = sshbuf_put_u8(b, 0)) != 0) return r; } for (i = 0; i < PROPOSAL_MAX; i++) { if ((r = sshbuf_put_cstring(b, proposal[i])) != 0) return r; } if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */ (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */ return r; return 0; } /* parse buffer and return algorithm proposal */ int kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) { struct sshbuf *b = NULL; u_char v; u_int i; char **proposal = NULL; int r; *propp = NULL; if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL) return SSH_ERR_ALLOC_FAIL; if ((b = sshbuf_fromb(raw)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */ goto out; /* extract kex init proposal strings */ for (i = 0; i < PROPOSAL_MAX; i++) { if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) goto out; debug2("%s: %s", proposal_names[i], proposal[i]); } /* first kex follows / reserved */ if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */ (r = sshbuf_get_u32(b, &i)) != 0) /* reserved */ goto out; if (first_kex_follows != NULL) *first_kex_follows = v; debug2("first_kex_follows %d ", v); debug2("reserved %u ", i); r = 0; *propp = proposal; out: if (r != 0 && proposal != NULL) kex_prop_free(proposal); sshbuf_free(b); return r; } void kex_prop_free(char **proposal) { u_int i; if (proposal == NULL) return; for (i = 0; i < PROPOSAL_MAX; i++) free(proposal[i]); free(proposal); } /* ARGSUSED */ static int kex_protocol_error(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = active_state; /* XXX */ int r; error("kex protocol error: type %d seq %u", type, seq); if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || (r = sshpkt_put_u32(ssh, seq)) != 0 || (r = sshpkt_send(ssh)) != 0) return r; return 0; } static void kex_reset_dispatch(struct ssh *ssh) { ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); } static int kex_send_ext_info(struct ssh *ssh) { int r; if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || (r = sshpkt_put_u32(ssh, 1)) != 0 || (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 || (r = sshpkt_send(ssh)) != 0) return r; return 0; } int kex_send_newkeys(struct ssh *ssh) { int r; kex_reset_dispatch(ssh); if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 || (r = sshpkt_send(ssh)) != 0) return r; debug("SSH2_MSG_NEWKEYS sent"); debug("expecting SSH2_MSG_NEWKEYS"); ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); if (ssh->kex->ext_info_c) if ((r = kex_send_ext_info(ssh)) != 0) return r; return 0; } int kex_input_ext_info(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; u_int32_t i, ninfo; char *name, *val, *found; int r; debug("SSH2_MSG_EXT_INFO received"); ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error); if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0) return r; for (i = 0; i < ninfo; i++) { if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) return r; if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) { free(name); return r; } debug("%s: %s=<%s>", __func__, name, val); if (strcmp(name, "server-sig-algs") == 0) { found = match_list("rsa-sha2-256", val, NULL); if (found) { kex->rsa_sha2 = 256; free(found); } found = match_list("rsa-sha2-512", val, NULL); if (found) { kex->rsa_sha2 = 512; free(found); } } free(name); free(val); } return sshpkt_get_end(ssh); } static int kex_input_newkeys(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; int r; debug("SSH2_MSG_NEWKEYS received"); ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); if ((r = sshpkt_get_end(ssh)) != 0) return r; kex->done = 1; sshbuf_reset(kex->peer); /* sshbuf_reset(kex->my); */ kex->flags &= ~KEX_INIT_SENT; free(kex->name); kex->name = NULL; return 0; } int kex_send_kexinit(struct ssh *ssh) { u_char *cookie; struct kex *kex = ssh->kex; int r; if (kex == NULL) return SSH_ERR_INTERNAL_ERROR; if (kex->flags & KEX_INIT_SENT) return 0; kex->done = 0; /* generate a random cookie */ if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) return SSH_ERR_INVALID_FORMAT; if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) return SSH_ERR_INTERNAL_ERROR; arc4random_buf(cookie, KEX_COOKIE_LEN); if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 || (r = sshpkt_putb(ssh, kex->my)) != 0 || (r = sshpkt_send(ssh)) != 0) return r; debug("SSH2_MSG_KEXINIT sent"); kex->flags |= KEX_INIT_SENT; return 0; } /* ARGSUSED */ int kex_input_kexinit(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; const u_char *ptr; u_int i; size_t dlen; int r; debug("SSH2_MSG_KEXINIT received"); if (kex == NULL) return SSH_ERR_INVALID_ARGUMENT; ptr = sshpkt_ptr(ssh, &dlen); if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) return r; /* discard packet */ for (i = 0; i < KEX_COOKIE_LEN; i++) if ((r = sshpkt_get_u8(ssh, NULL)) != 0) return r; for (i = 0; i < PROPOSAL_MAX; i++) if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) return r; /* * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported * KEX method has the server move first, but a server might be using * a custom method or one that we otherwise don't support. We should * be prepared to remember first_kex_follows here so we can eat a * packet later. * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means * for cases where the server *doesn't* go first. I guess we should * ignore it when it is set for these cases, which is what we do now. */ if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */ (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */ (r = sshpkt_get_end(ssh)) != 0) return r; if (!(kex->flags & KEX_INIT_SENT)) if ((r = kex_send_kexinit(ssh)) != 0) return r; if ((r = kex_choose_conf(ssh)) != 0) return r; if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) return (kex->kex[kex->kex_type])(ssh); return SSH_ERR_INTERNAL_ERROR; } int kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp) { struct kex *kex; int r; *kexp = NULL; if ((kex = calloc(1, sizeof(*kex))) == NULL) return SSH_ERR_ALLOC_FAIL; if ((kex->peer = sshbuf_new()) == NULL || (kex->my = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = kex_prop2buf(kex->my, proposal)) != 0) goto out; kex->done = 0; kex_reset_dispatch(ssh); r = 0; *kexp = kex; out: if (r != 0) kex_free(kex); return r; } void kex_free_newkeys(struct newkeys *newkeys) { if (newkeys == NULL) return; if (newkeys->enc.key) { explicit_bzero(newkeys->enc.key, newkeys->enc.key_len); free(newkeys->enc.key); newkeys->enc.key = NULL; } if (newkeys->enc.iv) { explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len); free(newkeys->enc.iv); newkeys->enc.iv = NULL; } free(newkeys->enc.name); explicit_bzero(&newkeys->enc, sizeof(newkeys->enc)); free(newkeys->comp.name); explicit_bzero(&newkeys->comp, sizeof(newkeys->comp)); mac_clear(&newkeys->mac); if (newkeys->mac.key) { explicit_bzero(newkeys->mac.key, newkeys->mac.key_len); free(newkeys->mac.key); newkeys->mac.key = NULL; } free(newkeys->mac.name); explicit_bzero(&newkeys->mac, sizeof(newkeys->mac)); explicit_bzero(newkeys, sizeof(*newkeys)); free(newkeys); } void kex_free(struct kex *kex) { u_int mode; #ifdef WITH_OPENSSL if (kex->dh) DH_free(kex->dh); #ifdef OPENSSL_HAS_ECC if (kex->ec_client_key) EC_KEY_free(kex->ec_client_key); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(kex->newkeys[mode]); kex->newkeys[mode] = NULL; } sshbuf_free(kex->peer); sshbuf_free(kex->my); free(kex->session_id); free(kex->client_version_string); free(kex->server_version_string); free(kex->failed_choice); free(kex->hostkey_alg); free(kex->name); free(kex); } int kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) { int r; if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) return r; if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ kex_free(ssh->kex); ssh->kex = NULL; return r; } return 0; } /* * Request key re-exchange, returns 0 on success or a ssherr.h error * code otherwise. Must not be called if KEX is incomplete or in-progress. */ int kex_start_rekex(struct ssh *ssh) { if (ssh->kex == NULL) { error("%s: no kex", __func__); return SSH_ERR_INTERNAL_ERROR; } if (ssh->kex->done == 0) { error("%s: requested twice", __func__); return SSH_ERR_INTERNAL_ERROR; } ssh->kex->done = 0; return kex_send_kexinit(ssh); } static int choose_enc(struct sshenc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) return SSH_ERR_NO_CIPHER_ALG_MATCH; if ((enc->cipher = cipher_by_name(name)) == NULL) return SSH_ERR_INTERNAL_ERROR; enc->name = name; enc->enabled = 0; enc->iv = NULL; enc->iv_len = cipher_ivlen(enc->cipher); enc->key = NULL; enc->key_len = cipher_keylen(enc->cipher); enc->block_size = cipher_blocksize(enc->cipher); return 0; } static int choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) return SSH_ERR_NO_MAC_ALG_MATCH; if (mac_setup(mac, name) < 0) return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ if (ssh->compat & SSH_BUG_HMAC) mac->key_len = 16; mac->name = name; mac->key = NULL; mac->enabled = 0; return 0; } static int choose_comp(struct sshcomp *comp, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) return SSH_ERR_NO_COMPRESS_ALG_MATCH; if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { comp->type = COMP_ZLIB; } else if (strcmp(name, "none") == 0) { comp->type = COMP_NONE; } else { return SSH_ERR_INTERNAL_ERROR; } comp->name = name; return 0; } static int choose_kex(struct kex *k, char *client, char *server) { const struct kexalg *kexalg; k->name = match_list(client, server, NULL); debug("kex: algorithm: %s", k->name ? k->name : "(no match)"); if (k->name == NULL) return SSH_ERR_NO_KEX_ALG_MATCH; if ((kexalg = kex_alg_by_name(k->name)) == NULL) return SSH_ERR_INTERNAL_ERROR; k->kex_type = kexalg->type; k->hash_alg = kexalg->hash_alg; k->ec_nid = kexalg->ec_nid; return 0; } static int choose_hostkeyalg(struct kex *k, char *client, char *server) { k->hostkey_alg = match_list(client, server, NULL); debug("kex: host key algorithm: %s", k->hostkey_alg ? k->hostkey_alg : "(no match)"); if (k->hostkey_alg == NULL) return SSH_ERR_NO_HOSTKEY_ALG_MATCH; k->hostkey_type = sshkey_type_from_name(k->hostkey_alg); if (k->hostkey_type == KEY_UNSPEC) return SSH_ERR_INTERNAL_ERROR; k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg); return 0; } static int proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) { static int check[] = { PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1 }; int *idx; char *p; for (idx = &check[0]; *idx != -1; idx++) { if ((p = strchr(my[*idx], ',')) != NULL) *p = '\0'; if ((p = strchr(peer[*idx], ',')) != NULL) *p = '\0'; if (strcmp(my[*idx], peer[*idx]) != 0) { debug2("proposal mismatch: my %s peer %s", my[*idx], peer[*idx]); return (0); } } debug2("proposals match"); return (1); } static int kex_choose_conf(struct ssh *ssh) { struct kex *kex = ssh->kex; struct newkeys *newkeys; char **my = NULL, **peer = NULL; char **cprop, **sprop; int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) goto out; debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server"); if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) goto out; if (kex->server) { cprop=peer; sprop=my; } else { cprop=my; sprop=peer; } /* Check whether client supports ext_info_c */ if (kex->server) { char *ext; ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); if (ext) { kex->ext_info_c = 1; free(ext); } } /* Algorithm Negotiation */ if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS])) != 0) { kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; peer[PROPOSAL_KEX_ALGS] = NULL; goto out; } if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS]; peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; goto out; } for (mode = 0; mode < MODE_MAX; mode++) { if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } kex->newkeys[mode] = newkeys; ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; if ((r = choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; goto out; } authlen = cipher_authlen(newkeys->enc.cipher); /* ignore mac for authenticated encryption */ if (authlen == 0 && (r = choose_mac(ssh, &newkeys->mac, cprop[nmac], sprop[nmac])) != 0) { kex->failed_choice = peer[nmac]; peer[nmac] = NULL; goto out; } if ((r = choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; goto out; } debug("kex: %s cipher: %s MAC: %s compression: %s", ctos ? "client->server" : "server->client", newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; need = MAX(need, newkeys->enc.key_len); need = MAX(need, newkeys->enc.block_size); need = MAX(need, newkeys->enc.iv_len); need = MAX(need, newkeys->mac.key_len); dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher)); dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); } /* XXX need runden? */ kex->we_need = need; kex->dh_need = dh_need; /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && !(ssh->compat & SSH_BUG_FIRSTKEX)) ssh->dispatch_skip_packets = 1; r = 0; out: kex_prop_free(my); kex_prop_free(peer); return r; } static int derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, const struct sshbuf *shared_secret, u_char **keyp) { struct kex *kex = ssh->kex; struct ssh_digest_ctx *hashctx = NULL; char c = id; u_int have; size_t mdsz; u_char *digest; int r; if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) return SSH_ERR_INVALID_ARGUMENT; if ((digest = calloc(1, roundup(need, mdsz))) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* K1 = HASH(K || H || "A" || session_id) */ if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || ssh_digest_update_buffer(hashctx, shared_secret) != 0 || ssh_digest_update(hashctx, hash, hashlen) != 0 || ssh_digest_update(hashctx, &c, 1) != 0 || ssh_digest_update(hashctx, kex->session_id, kex->session_id_len) != 0 || ssh_digest_final(hashctx, digest, mdsz) != 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } ssh_digest_free(hashctx); hashctx = NULL; /* * expand key: * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) * Key = K1 || K2 || ... || Kn */ for (have = mdsz; need > have; have += mdsz) { if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || ssh_digest_update_buffer(hashctx, shared_secret) != 0 || ssh_digest_update(hashctx, hash, hashlen) != 0 || ssh_digest_update(hashctx, digest, have) != 0 || ssh_digest_final(hashctx, digest + have, mdsz) != 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } ssh_digest_free(hashctx); hashctx = NULL; } #ifdef DEBUG_KEX fprintf(stderr, "key '%c'== ", c); dump_digest("key", digest, need); #endif *keyp = digest; digest = NULL; r = 0; out: free(digest); ssh_digest_free(hashctx); return r; } #define NKEYS 6 int kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen, const struct sshbuf *shared_secret) { struct kex *kex = ssh->kex; u_char *keys[NKEYS]; u_int i, j, mode, ctos; int r; for (i = 0; i < NKEYS; i++) { if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen, shared_secret, &keys[i])) != 0) { for (j = 0; j < i; j++) free(keys[j]); return r; } } for (mode = 0; mode < MODE_MAX; mode++) { ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1]; kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3]; kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5]; } return 0; } #ifdef WITH_OPENSSL int kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen, const BIGNUM *secret) { struct sshbuf *shared_secret; int r; if ((shared_secret = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0) r = kex_derive_keys(ssh, hash, hashlen, shared_secret); sshbuf_free(shared_secret); return r; } #endif #ifdef WITH_SSH1 int derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, u_int8_t cookie[8], u_int8_t id[16]) { u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; struct ssh_digest_ctx *hashctx = NULL; size_t hlen, slen; int r; hlen = BN_num_bytes(host_modulus); slen = BN_num_bytes(server_modulus); if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) || slen < (512 / 8) || (u_int)slen > sizeof(sbuf)) return SSH_ERR_KEY_BITS_MISMATCH; if (BN_bn2bin(host_modulus, hbuf) <= 0 || BN_bn2bin(server_modulus, sbuf) <= 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (ssh_digest_update(hashctx, hbuf, hlen) != 0 || ssh_digest_update(hashctx, sbuf, slen) != 0 || ssh_digest_update(hashctx, cookie, 8) != 0 || ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); r = 0; out: ssh_digest_free(hashctx); explicit_bzero(hbuf, sizeof(hbuf)); explicit_bzero(sbuf, sizeof(sbuf)); explicit_bzero(obuf, sizeof(obuf)); return r; } #endif #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) void dump_digest(char *msg, u_char *digest, int len) { fprintf(stderr, "%s\n", msg); sshbuf_dump_data(digest, len, stderr); } #endif openssh-7.2p2/kex.h010064400017500001750000000160231267006270000124140ustar00djmdjm/* $OpenBSD: kex.h,v 1.76 2016/02/08 10:57:07 djm Exp $ */ /* * Copyright (c) 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 KEX_H #define KEX_H #include "mac.h" #include "buffer.h" /* XXX for typedef */ #include "key.h" /* XXX for typedef */ #ifdef WITH_LEAKMALLOC #include "leakmalloc.h" #endif #ifdef WITH_OPENSSL # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ # define EC_KEY void # define EC_GROUP void # define EC_POINT void # endif /* OPENSSL_HAS_ECC */ #else /* WITH_OPENSSL */ # define EC_KEY void # define EC_GROUP void # define EC_POINT void #endif /* WITH_OPENSSL */ #define KEX_COOKIE_LEN 16 #define KEX_DH1 "diffie-hellman-group1-sha1" #define KEX_DH14 "diffie-hellman-group14-sha1" #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" #define KEX_CURVE25519_SHA256 "curve25519-sha256@libssh.org" #define COMP_NONE 0 #define COMP_ZLIB 1 #define COMP_DELAYED 2 #define CURVE25519_SIZE 32 enum kex_init_proposals { PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, PROPOSAL_ENC_ALGS_CTOS, PROPOSAL_ENC_ALGS_STOC, PROPOSAL_MAC_ALGS_CTOS, PROPOSAL_MAC_ALGS_STOC, PROPOSAL_COMP_ALGS_CTOS, PROPOSAL_COMP_ALGS_STOC, PROPOSAL_LANG_CTOS, PROPOSAL_LANG_STOC, PROPOSAL_MAX }; enum kex_modes { MODE_IN, MODE_OUT, MODE_MAX }; enum kex_exchange { KEX_DH_GRP1_SHA1, KEX_DH_GRP14_SHA1, KEX_DH_GEX_SHA1, KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, KEX_C25519_SHA256, KEX_MAX }; #define KEX_INIT_SENT 0x0001 struct sshenc { char *name; const struct sshcipher *cipher; int enabled; u_int key_len; u_int iv_len; u_int block_size; u_char *key; u_char *iv; }; struct sshcomp { u_int type; int enabled; char *name; }; struct newkeys { struct sshenc enc; struct sshmac mac; struct sshcomp comp; }; struct ssh; struct kex { u_char *session_id; size_t session_id_len; struct newkeys *newkeys[MODE_MAX]; u_int we_need; u_int dh_need; int server; char *name; char *hostkey_alg; int hostkey_type; int hostkey_nid; u_int kex_type; int rsa_sha2; int ext_info_c; struct sshbuf *my; struct sshbuf *peer; sig_atomic_t done; u_int flags; int hash_alg; int ec_nid; char *client_version_string; char *server_version_string; char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); struct sshkey *(*load_host_private_key)(int, int, struct ssh *); int (*host_key_index)(struct sshkey *, int, struct ssh *); int (*sign)(struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); int (*kex[KEX_MAX])(struct ssh *); /* kex specific state */ DH *dh; /* DH */ u_int min, max, nbits; /* GEX */ EC_KEY *ec_client_key; /* ECDH */ const EC_GROUP *ec_group; /* ECDH */ u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 */ u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ }; int kex_names_valid(const char *); char *kex_alg_list(char); char *kex_names_cat(const char *, const char *); int kex_assemble_names(const char *, char **); int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); void kex_free_newkeys(struct newkeys *); void kex_free(struct kex *); int kex_buf2prop(struct sshbuf *, int *, char ***); int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); void kex_prop_free(char **); int kex_send_kexinit(struct ssh *); int kex_input_kexinit(int, u_int32_t, void *); int kex_input_ext_info(int, u_int32_t, void *); int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); int kex_send_newkeys(struct ssh *); int kex_start_rekex(struct ssh *); int kexdh_client(struct ssh *); int kexdh_server(struct ssh *); int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kexecdh_client(struct ssh *); int kexecdh_server(struct ssh *); int kexc25519_client(struct ssh *); int kexc25519_server(struct ssh *); int kex_dh_hash(const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); int kexgex_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, int, int, int, const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); int kex_ecdh_hash(int, const EC_GROUP *, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char *, size_t *); int kex_c25519_hash(int, const char *, const char *, const char *, size_t, const char *, size_t, const u_char *, size_t, const u_char *, const u_char *, const u_char *, size_t, u_char *, size_t *); void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], const u_char pub[CURVE25519_SIZE], struct sshbuf *out) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); int derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) void dump_digest(char *, u_char *, int); #endif #if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) # undef EC_KEY # undef EC_GROUP # undef EC_POINT #endif #endif openssh-7.2p2/kexc25519.c010064400017500001750000000111621267006270000131570ustar00djmdjm/* $OpenBSD: kexc25519.c,v 1.9 2015/03/26 07:00:04 djm Exp $ */ /* * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2013 Aris Adamantiadis. 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 #include #include #include #include #include "sshbuf.h" #include "ssh2.h" #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "log.h" #include "digest.h" #include "ssherr.h" extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE))); void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) { static const u_char basepoint[CURVE25519_SIZE] = {9}; arc4random_buf(key, CURVE25519_SIZE); crypto_scalarmult_curve25519(pub, key, basepoint); } int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], const u_char pub[CURVE25519_SIZE], struct sshbuf *out) { u_char shared_key[CURVE25519_SIZE]; int r; /* Check for all-zero public key */ explicit_bzero(shared_key, CURVE25519_SIZE); if (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0) return SSH_ERR_KEY_INVALID_EC_VALUE; crypto_scalarmult_curve25519(shared_key, key, pub); #ifdef DEBUG_KEXECDH dump_digest("shared secret", shared_key, CURVE25519_SIZE); #endif sshbuf_reset(out); r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE); explicit_bzero(shared_key, CURVE25519_SIZE); return r; } int kex_c25519_hash( int hash_alg, const char *client_version_string, const char *server_version_string, const char *ckexinit, size_t ckexinitlen, const char *skexinit, size_t skexinitlen, const u_char *serverhostkeyblob, size_t sbloblen, const u_char client_dh_pub[CURVE25519_SIZE], const u_char server_dh_pub[CURVE25519_SIZE], const u_char *shared_secret, size_t secretlen, u_char *hash, size_t *hashlen) { struct sshbuf *b; int r; if (*hashlen < ssh_digest_bytes(hash_alg)) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 || (r = sshbuf_put_cstring(b, server_version_string)) < 0 || /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 || (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 || (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 || (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 || (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 || (r = sshbuf_put(b, shared_secret, secretlen)) < 0) { sshbuf_free(b); return r; } #ifdef DEBUG_KEX sshbuf_dump(b, stderr); #endif if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { sshbuf_free(b); return SSH_ERR_LIBCRYPTO_ERROR; } sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); #ifdef DEBUG_KEX dump_digest("hash", hash, *hashlen); #endif return 0; } openssh-7.2p2/kexc25519c.c010064400017500001750000000121531267006270000133230ustar00djmdjm/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2013 Aris Adamantiadis. 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 #include #include #include #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" #include "sshbuf.h" #include "digest.h" #include "ssherr.h" static int input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt); int kexc25519_client(struct ssh *ssh) { struct kex *kex = ssh->kex; int r; kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey); #ifdef DEBUG_KEXECDH dump_digest("client private key:", kex->c25519_client_key, sizeof(kex->c25519_client_key)); #endif if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 || (r = sshpkt_put_string(ssh, kex->c25519_client_pubkey, sizeof(kex->c25519_client_pubkey))) != 0 || (r = sshpkt_send(ssh)) != 0) return r; debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_c25519_reply); return 0; } static int input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; struct sshkey *server_host_key = NULL; struct sshbuf *shared_secret = NULL; u_char *server_pubkey = NULL; u_char *server_host_key_blob = NULL, *signature = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t slen, pklen, sbloblen, hashlen; int r; if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } /* hostkey */ if ((r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen)) != 0 || (r = sshkey_from_blob(server_host_key_blob, sbloblen, &server_host_key)) != 0) goto out; if (server_host_key->type != kex->hostkey_type || (kex->hostkey_type == KEY_ECDSA && server_host_key->ecdsa_nid != kex->hostkey_nid)) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (kex->verify_host_key(server_host_key, ssh) == -1) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } /* Q_S, server public key */ /* signed H */ if ((r = sshpkt_get_string(ssh, &server_pubkey, &pklen)) != 0 || (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; if (pklen != CURVE25519_SIZE) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } #ifdef DEBUG_KEXECDH dump_digest("server public key:", server_pubkey, CURVE25519_SIZE); #endif if ((shared_secret = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = kexc25519_shared_key(kex->c25519_client_key, server_pubkey, shared_secret)) < 0) goto out; /* calc and verify H */ hashlen = sizeof(hash); if ((r = kex_c25519_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, kex->c25519_client_pubkey, server_pubkey, sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), hash, &hashlen)) < 0) goto out; if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, ssh->compat)) != 0) goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); free(server_host_key_blob); free(server_pubkey); free(signature); sshkey_free(server_host_key); sshbuf_free(shared_secret); return r; } openssh-7.2p2/kexc25519s.c010064400017500001750000000120111267006270000133340ustar00djmdjm/* $OpenBSD: kexc25519s.c,v 1.10 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2013 Aris Adamantiadis. All rights reserved. * * 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 #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" #include "sshbuf.h" #include "ssherr.h" static int input_kex_c25519_init(int, u_int32_t, void *); int kexc25519_server(struct ssh *ssh) { debug("expecting SSH2_MSG_KEX_ECDH_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_c25519_init); return 0; } static int input_kex_c25519_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; struct sshkey *server_host_private, *server_host_public; struct sshbuf *shared_secret = NULL; u_char *server_host_key_blob = NULL, *signature = NULL; u_char server_key[CURVE25519_SIZE]; u_char *client_pubkey = NULL; u_char server_pubkey[CURVE25519_SIZE]; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t slen, pklen, sbloblen, hashlen; int r; /* generate private key */ kexc25519_keygen(server_key, server_pubkey); #ifdef DEBUG_KEXECDH dump_digest("server private key:", server_key, sizeof(server_key)); #endif if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, kex->hostkey_nid, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, kex->hostkey_nid, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } if ((r = sshpkt_get_string(ssh, &client_pubkey, &pklen)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; if (pklen != CURVE25519_SIZE) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } #ifdef DEBUG_KEXECDH dump_digest("client public key:", client_pubkey, CURVE25519_SIZE); #endif if ((shared_secret = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = kexc25519_shared_key(server_key, client_pubkey, shared_secret)) < 0) goto out; /* calc H */ if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; hashlen = sizeof(hash); if ((r = kex_c25519_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, client_pubkey, server_pubkey, sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), hash, &hashlen)) < 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_string(ssh, server_pubkey, sizeof(server_pubkey))) != 0 || (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); explicit_bzero(server_key, sizeof(server_key)); free(server_host_key_blob); free(signature); free(client_pubkey); sshbuf_free(shared_secret); return r; } openssh-7.2p2/kexdh.c010064400017500001750000000063561267006270000127330ustar00djmdjm/* $OpenBSD: kexdh.c,v 1.25 2015/01/19 20:16:15 markus 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 WITH_OPENSSL #include #include #include #include "ssh2.h" #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "ssherr.h" #include "sshbuf.h" #include "digest.h" int kex_dh_hash( const char *client_version_string, const char *server_version_string, const u_char *ckexinit, size_t ckexinitlen, const u_char *skexinit, size_t skexinitlen, const u_char *serverhostkeyblob, size_t sbloblen, const BIGNUM *client_dh_pub, const BIGNUM *server_dh_pub, const BIGNUM *shared_secret, u_char *hash, size_t *hashlen) { struct sshbuf *b; int r; if (*hashlen < ssh_digest_bytes(SSH_DIGEST_SHA1)) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || (r = sshbuf_put_cstring(b, server_version_string)) != 0 || /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { sshbuf_free(b); return r; } #ifdef DEBUG_KEX sshbuf_dump(b, stderr); #endif if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, hash, *hashlen) != 0) { sshbuf_free(b); return SSH_ERR_LIBCRYPTO_ERROR; } sshbuf_free(b); *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1); #ifdef DEBUG_KEX dump_digest("hash", hash, *hashlen); #endif return 0; } #endif /* WITH_OPENSSL */ openssh-7.2p2/kexdhc.c010064400017500001750000000135341267006270000130720ustar00djmdjm/* $OpenBSD: kexdhc.c,v 1.18 2015/01/26 06:10:03 djm 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 WITH_OPENSSL #include #include #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "dispatch.h" #include "compat.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_dh(int, u_int32_t, void *); int kexdh_client(struct ssh *ssh) { struct kex *kex = ssh->kex; int r; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: kex->dh = dh_new_group14(); break; default: r = SSH_ERR_INVALID_ARGUMENT; goto out; } if (kex->dh == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } debug("sending SSH2_MSG_KEXDH_INIT"); if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif debug("expecting SSH2_MSG_KEXDH_REPLY"); ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); r = 0; out: return r; } static int input_kex_dh(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; struct sshkey *server_host_key = NULL; u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } /* key, cert */ if ((r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen)) != 0 || (r = sshkey_from_blob(server_host_key_blob, sbloblen, &server_host_key)) != 0) goto out; if (server_host_key->type != kex->hostkey_type || (kex->hostkey_type == KEY_ECDSA && server_host_key->ecdsa_nid != kex->hostkey_nid)) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (kex->verify_host_key(server_host_key, ssh) == -1) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } /* DH parameter f, server public DH key */ if ((dh_server_pub = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* signed H */ if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 || (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { sshpkt_disconnect(ssh, "bad server public DH value"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = DH_size(kex->dh); if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || BN_bin2bn(kbuf, kout, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif /* calc and verify H */ hashlen = sizeof(hash); if ((r = kex_dh_hash( kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, kex->dh->pub_key, dh_server_pub, shared_secret, hash, &hashlen)) != 0) goto out; if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, ssh->compat)) != 0) goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); kex->dh = NULL; if (dh_server_pub) BN_clear_free(dh_server_pub); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); sshkey_free(server_host_key); free(server_host_key_blob); free(signature); return r; } #endif /* WITH_OPENSSL */ openssh-7.2p2/kexdhs.c010064400017500001750000000136171267006270000131140ustar00djmdjm/* $OpenBSD: kexdhs.c,v 1.23 2015/12/04 16:41:28 markus 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 WITH_OPENSSL #include #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "dispatch.h" #include "compat.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_dh_init(int, u_int32_t, void *); int kexdh_server(struct ssh *ssh) { struct kex *kex = ssh->kex; int r; /* generate server DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: kex->dh = dh_new_group14(); break; default: r = SSH_ERR_INVALID_ARGUMENT; goto out; } if (kex->dh == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) goto out; debug("expecting SSH2_MSG_KEXDH_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); r = 0; out: return r; } int input_kex_dh_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; struct sshkey *server_host_public, *server_host_private; u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, kex->hostkey_nid, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, kex->hostkey_nid, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } /* key, cert */ if ((dh_client_pub = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_client_pub= "); BN_print_fp(stderr, dh_client_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_client_pub)); #endif #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { sshpkt_disconnect(ssh, "bad client public DH value"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = DH_size(kex->dh); if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || BN_bin2bn(kbuf, kout, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; /* calc H */ hashlen = sizeof(hash); if ((r = kex_dh_hash( kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, dh_client_pub, kex->dh->pub_key, shared_secret, hash, &hashlen)) != 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); kex->dh = NULL; if (dh_client_pub) BN_clear_free(dh_client_pub); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); free(server_host_key_blob); free(signature); return r; } #endif /* WITH_OPENSSL */ openssh-7.2p2/kexecdh.c010064400017500001750000000067721267006270000132450ustar00djmdjm/* $OpenBSD: kexecdh.c,v 1.6 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 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" #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include #include #include #include #include #include #include #include "ssh2.h" #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "sshbuf.h" #include "digest.h" #include "ssherr.h" int kex_ecdh_hash( int hash_alg, const EC_GROUP *ec_group, const char *client_version_string, const char *server_version_string, const u_char *ckexinit, size_t ckexinitlen, const u_char *skexinit, size_t skexinitlen, const u_char *serverhostkeyblob, size_t sbloblen, const EC_POINT *client_dh_pub, const EC_POINT *server_dh_pub, const BIGNUM *shared_secret, u_char *hash, size_t *hashlen) { struct sshbuf *b; int r; if (*hashlen < ssh_digest_bytes(hash_alg)) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || (r = sshbuf_put_cstring(b, server_version_string)) != 0 || /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || (r = sshbuf_put_ec(b, client_dh_pub, ec_group)) != 0 || (r = sshbuf_put_ec(b, server_dh_pub, ec_group)) != 0 || (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { sshbuf_free(b); return r; } #ifdef DEBUG_KEX sshbuf_dump(b, stderr); #endif if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { sshbuf_free(b); return SSH_ERR_LIBCRYPTO_ERROR; } sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); #ifdef DEBUG_KEX dump_digest("hash", hash, *hashlen); #endif return 0; } #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ openssh-7.2p2/kexecdhc.c010064400017500001750000000144631267006270000134040ustar00djmdjm/* $OpenBSD: kexecdhc.c,v 1.10 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 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" #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "dispatch.h" #include "compat.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_ecdh_reply(int, u_int32_t, void *); int kexecdh_client(struct ssh *ssh) { struct kex *kex = ssh->kex; EC_KEY *client_key = NULL; const EC_GROUP *group; const EC_POINT *public_key; int r; if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (EC_KEY_generate_key(client_key) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } group = EC_KEY_get0_group(client_key); public_key = EC_KEY_get0_public_key(client_key); if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 || (r = sshpkt_put_ec(ssh, public_key, group)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; debug("sending SSH2_MSG_KEX_ECDH_INIT"); #ifdef DEBUG_KEXECDH fputs("client private key:\n", stderr); sshkey_dump_ec_key(client_key); #endif kex->ec_client_key = client_key; kex->ec_group = group; client_key = NULL; /* owned by the kex */ debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_ecdh_reply); r = 0; out: if (client_key) EC_KEY_free(client_key); return r; } static int input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; const EC_GROUP *group; EC_POINT *server_public = NULL; EC_KEY *client_key; BIGNUM *shared_secret = NULL; struct sshkey *server_host_key = NULL; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t slen, sbloblen; size_t klen = 0, hashlen; int r; if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } group = kex->ec_group; client_key = kex->ec_client_key; /* hostkey */ if ((r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen)) != 0 || (r = sshkey_from_blob(server_host_key_blob, sbloblen, &server_host_key)) != 0) goto out; if (server_host_key->type != kex->hostkey_type || (kex->hostkey_type == KEY_ECDSA && server_host_key->ecdsa_nid != kex->hostkey_nid)) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (kex->verify_host_key(server_host_key, ssh) == -1) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } /* Q_S, server public key */ /* signed H */ if ((server_public = EC_POINT_new(group)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_ec(ssh, server_public, group)) != 0 || (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXECDH fputs("server public key:\n", stderr); sshkey_dump_ec_point(group, server_public); #endif if (sshkey_ec_validate_public(group, server_public) != 0) { sshpkt_disconnect(ssh, "invalid server public key"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = (EC_GROUP_get_degree(group) + 7) / 8; if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (ECDH_compute_key(kbuf, klen, server_public, client_key, NULL) != (int)klen || BN_bin2bn(kbuf, klen, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif /* calc and verify H */ hashlen = sizeof(hash); if ((r = kex_ecdh_hash( kex->hash_alg, group, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, EC_KEY_get0_public_key(client_key), server_public, shared_secret, hash, &hashlen)) != 0) goto out; if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, ssh->compat)) != 0) goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); if (kex->ec_client_key) { EC_KEY_free(kex->ec_client_key); kex->ec_client_key = NULL; } if (server_public) EC_POINT_clear_free(server_public); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); sshkey_free(server_host_key); free(server_host_key_blob); free(signature); return r; } #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ openssh-7.2p2/kexecdhs.c010064400017500001750000000140261267006270000134170ustar00djmdjm/* $OpenBSD: kexecdhs.c,v 1.15 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 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" #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" #include "dispatch.h" #include "compat.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_ecdh_init(int, u_int32_t, void *); int kexecdh_server(struct ssh *ssh) { debug("expecting SSH2_MSG_KEX_ECDH_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_ecdh_init); return 0; } static int input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; EC_POINT *client_public; EC_KEY *server_key = NULL; const EC_GROUP *group; const EC_POINT *public_key; BIGNUM *shared_secret = NULL; struct sshkey *server_host_private, *server_host_public; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t slen, sbloblen; size_t klen = 0, hashlen; int r; if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (EC_KEY_generate_key(server_key) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } group = EC_KEY_get0_group(server_key); #ifdef DEBUG_KEXECDH fputs("server private key:\n", stderr); sshkey_dump_ec_key(server_key); #endif if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, kex->hostkey_nid, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, kex->hostkey_nid, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } if ((client_public = EC_POINT_new(group)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXECDH fputs("client public key:\n", stderr); sshkey_dump_ec_point(group, client_public); #endif if (sshkey_ec_validate_public(group, client_public) != 0) { sshpkt_disconnect(ssh, "invalid client public key"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } /* Calculate shared_secret */ klen = (EC_GROUP_get_degree(group) + 7) / 8; if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (ECDH_compute_key(kbuf, klen, client_public, server_key, NULL) != (int)klen || BN_bin2bn(kbuf, klen, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif /* calc H */ if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; hashlen = sizeof(hash); if ((r = kex_ecdh_hash( kex->hash_alg, group, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, client_public, EC_KEY_get0_public_key(server_key), shared_secret, hash, &hashlen)) != 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ public_key = EC_KEY_get0_public_key(server_key); /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_ec(ssh, public_key, group)) != 0 || (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); if (kex->ec_client_key) { EC_KEY_free(kex->ec_client_key); kex->ec_client_key = NULL; } if (server_key) EC_KEY_free(server_key); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); free(server_host_key_blob); free(signature); return r; } #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ openssh-7.2p2/kexgex.c010064400017500001750000000072031267006270000131130ustar00djmdjm/* $OpenBSD: kexgex.c,v 1.29 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 WITH_OPENSSL #include #include #include #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "ssh2.h" #include "ssherr.h" #include "sshbuf.h" #include "digest.h" int kexgex_hash( int hash_alg, const char *client_version_string, const char *server_version_string, const u_char *ckexinit, size_t ckexinitlen, const u_char *skexinit, size_t skexinitlen, const u_char *serverhostkeyblob, size_t sbloblen, int min, int wantbits, int max, const BIGNUM *prime, const BIGNUM *gen, const BIGNUM *client_dh_pub, const BIGNUM *server_dh_pub, const BIGNUM *shared_secret, u_char *hash, size_t *hashlen) { struct sshbuf *b; int r; if (*hashlen < ssh_digest_bytes(SSH_DIGEST_SHA1)) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || (r = sshbuf_put_cstring(b, server_version_string)) != 0 || /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || (min != -1 && (r = sshbuf_put_u32(b, min)) != 0) || (r = sshbuf_put_u32(b, wantbits)) != 0 || (max != -1 && (r = sshbuf_put_u32(b, max)) != 0) || (r = sshbuf_put_bignum2(b, prime)) != 0 || (r = sshbuf_put_bignum2(b, gen)) != 0 || (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { sshbuf_free(b); return r; } #ifdef DEBUG_KEXDH sshbuf_dump(b, stderr); #endif if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { sshbuf_free(b); return SSH_ERR_LIBCRYPTO_ERROR; } sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); #ifdef DEBUG_KEXDH dump_digest("hash", hash, *hashlen); #endif return 0; } #endif /* WITH_OPENSSL */ openssh-7.2p2/kexgexc.c010064400017500001750000000171561267006270000132660ustar00djmdjm/* $OpenBSD: kexgexc.c,v 1.22 2015/05/26 23:23:40 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 WITH_OPENSSL #include #include #include #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "compat.h" #include "dispatch.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_dh_gex_group(int, u_int32_t, void *); static int input_kex_dh_gex_reply(int, u_int32_t, void *); int kexgex_client(struct ssh *ssh) { struct kex *kex = ssh->kex; int r; u_int nbits; nbits = dh_estimate(kex->dh_need * 8); kex->min = DH_GRP_MIN; kex->max = DH_GRP_MAX; kex->nbits = nbits; if (datafellows & SSH_BUG_DHGEX_LARGE) kex->nbits = MIN(kex->nbits, 4096); /* New GEX request */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 || (r = sshpkt_put_u32(ssh, kex->min)) != 0 || (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || (r = sshpkt_put_u32(ssh, kex->max)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", kex->min, kex->nbits, kex->max); #ifdef DEBUG_KEXDH fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", kex->min, kex->nbits, kex->max); #endif ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, &input_kex_dh_gex_group); r = 0; out: return r; } static int input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *p = NULL, *g = NULL; int r, bits; debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); if ((p = BN_new()) == NULL || (g = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_bignum2(ssh, p)) != 0 || (r = sshpkt_get_bignum2(ssh, g)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; if ((bits = BN_num_bits(p)) < 0 || (u_int)bits < kex->min || (u_int)bits > kex->max) { r = SSH_ERR_DH_GEX_OUT_OF_RANGE; goto out; } if ((kex->dh = dh_new_group(g, p)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); r = 0; out: if (p) BN_clear_free(p); if (g) BN_clear_free(g); return r; } static int input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; struct sshkey *server_host_key = NULL; u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } /* key, cert */ if ((r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen)) != 0 || (r = sshkey_from_blob(server_host_key_blob, sbloblen, &server_host_key)) != 0) goto out; if (server_host_key->type != kex->hostkey_type) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (server_host_key->type != kex->hostkey_type || (kex->hostkey_type == KEY_ECDSA && server_host_key->ecdsa_nid != kex->hostkey_nid)) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (kex->verify_host_key(server_host_key, ssh) == -1) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } /* DH parameter f, server public DH key */ if ((dh_server_pub = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* signed H */ if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 || (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { sshpkt_disconnect(ssh, "bad server public DH value"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = DH_size(kex->dh); if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || BN_bin2bn(kbuf, kout, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if (ssh->compat & SSH_OLD_DHGEX) kex->min = kex->max = -1; /* calc and verify H */ hashlen = sizeof(hash); if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, kex->dh->p, kex->dh->g, kex->dh->pub_key, dh_server_pub, shared_secret, hash, &hashlen)) != 0) goto out; if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, ssh->compat)) != 0) goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); kex->dh = NULL; if (dh_server_pub) BN_clear_free(dh_server_pub); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); sshkey_free(server_host_key); free(server_host_key_blob); free(signature); return r; } #endif /* WITH_OPENSSL */ openssh-7.2p2/kexgexs.c010064400017500001750000000163311267006270000133000ustar00djmdjm/* $OpenBSD: kexgexs.c,v 1.26 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 WITH_OPENSSL #include /* MIN MAX */ #include #include #include #include #include #include "sshkey.h" #include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "compat.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "dispatch.h" #include "ssherr.h" #include "sshbuf.h" static int input_kex_dh_gex_request(int, u_int32_t, void *); static int input_kex_dh_gex_init(int, u_int32_t, void *); int kexgex_server(struct ssh *ssh) { ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST, &input_kex_dh_gex_request); debug("expecting SSH2_MSG_KEX_DH_GEX_REQUEST"); return 0; } static int input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; int r; u_int min = 0, max = 0, nbits = 0; debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); if ((r = sshpkt_get_u32(ssh, &min)) != 0 || (r = sshpkt_get_u32(ssh, &nbits)) != 0 || (r = sshpkt_get_u32(ssh, &max)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; kex->nbits = nbits; kex->min = min; kex->max = max; min = MAX(DH_GRP_MIN, min); max = MIN(DH_GRP_MAX, max); nbits = MAX(DH_GRP_MIN, nbits); nbits = MIN(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || kex->max < kex->nbits) { r = SSH_ERR_DH_GEX_OUT_OF_RANGE; goto out; } /* Contact privileged parent */ kex->dh = PRIVSEP(choose_dh(min, nbits, max)); if (kex->dh == NULL) { sshpkt_disconnect(ssh, "no matching DH grp found"); r = SSH_ERR_ALLOC_FAIL; goto out; } debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; /* Compute our exchange value in parallel with the client */ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) goto out; debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); r = 0; out: return r; } static int input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = ctxt; struct kex *kex = ssh->kex; BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; struct sshkey *server_host_public, *server_host_private; u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } server_host_public = kex->load_host_public_key(kex->hostkey_type, kex->hostkey_nid, ssh); server_host_private = kex->load_host_private_key(kex->hostkey_type, kex->hostkey_nid, ssh); if (server_host_public == NULL) { r = SSH_ERR_NO_HOSTKEY_LOADED; goto out; } /* key, cert */ if ((dh_client_pub = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || (r = sshpkt_get_end(ssh)) != 0) goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_client_pub= "); BN_print_fp(stderr, dh_client_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_client_pub)); #endif #ifdef DEBUG_KEXDH DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { sshpkt_disconnect(ssh, "bad client public DH value"); r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } klen = DH_size(kex->dh); if ((kbuf = malloc(klen)) == NULL || (shared_secret = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || BN_bin2bn(kbuf, kout, shared_secret) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, &sbloblen)) != 0) goto out; /* calc H */ hashlen = sizeof(hash); if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, kex->dh->p, kex->dh->g, dh_client_pub, kex->dh->pub_key, shared_secret, hash, &hashlen)) != 0) goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; kex->session_id = malloc(kex->session_id_len); if (kex->session_id == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ if ((r = kex->sign(server_host_private, server_host_public, &signature, &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) r = kex_send_newkeys(ssh); out: DH_free(kex->dh); kex->dh = NULL; if (dh_client_pub) BN_clear_free(dh_client_pub); if (kbuf) { explicit_bzero(kbuf, klen); free(kbuf); } if (shared_secret) BN_clear_free(shared_secret); free(server_host_key_blob); free(signature); return r; } #endif /* WITH_OPENSSL */ openssh-7.2p2/key.c010064400017500001750000000206251267006270000124130ustar00djmdjm/* $OpenBSD: key.c,v 1.129 2015/12/04 16:41:28 markus Exp $ */ /* * placed in the public domain */ #include "includes.h" #include #include #include #include #include #define SSH_KEY_NO_DEFINE #include "key.h" #include "compat.h" #include "sshkey.h" #include "ssherr.h" #include "log.h" #include "authfile.h" void key_add_private(Key *k) { int r; if ((r = sshkey_add_private(k)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } Key * key_new_private(int type) { Key *ret = NULL; if ((ret = sshkey_new_private(type)) == NULL) fatal("%s: failed", __func__); return ret; } int key_read(Key *ret, char **cpp) { return sshkey_read(ret, cpp) == 0 ? 1 : -1; } int key_write(const Key *key, FILE *f) { return sshkey_write(key, f) == 0 ? 1 : 0; } Key * key_generate(int type, u_int bits) { int r; Key *ret = NULL; if ((r = sshkey_generate(type, bits, &ret)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return ret; } void key_cert_copy(const Key *from_key, Key *to_key) { int r; if ((r = sshkey_cert_copy(from_key, to_key)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } Key * key_from_private(const Key *k) { int r; Key *ret = NULL; if ((r = sshkey_from_private(k, &ret)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return ret; } static void fatal_on_fatal_errors(int r, const char *func, int extra_fatal) { if (r == SSH_ERR_INTERNAL_ERROR || r == SSH_ERR_ALLOC_FAIL || (extra_fatal != 0 && r == extra_fatal)) fatal("%s: %s", func, ssh_err(r)); } Key * key_from_blob(const u_char *blob, u_int blen) { int r; Key *ret = NULL; if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } int key_to_blob(const Key *key, u_char **blobp, u_int *lenp) { u_char *blob; size_t blen; int r; if (blobp != NULL) *blobp = NULL; if (lenp != NULL) *lenp = 0; if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return 0; } if (blen > INT_MAX) fatal("%s: giant len %zu", __func__, blen); if (blobp != NULL) *blobp = blob; if (lenp != NULL) *lenp = blen; return blen; } int key_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen, const char *alg) { int r; u_char *sig; size_t siglen; if (sigp != NULL) *sigp = NULL; if (lenp != NULL) *lenp = 0; if ((r = sshkey_sign(key, &sig, &siglen, data, datalen, alg, datafellows)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; } if (siglen > INT_MAX) fatal("%s: giant len %zu", __func__, siglen); if (sigp != NULL) *sigp = sig; if (lenp != NULL) *lenp = siglen; return 0; } int key_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { int r; if ((r = sshkey_verify(key, signature, signaturelen, data, datalen, datafellows)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1; } return 1; } Key * key_demote(const Key *k) { int r; Key *ret = NULL; if ((r = sshkey_demote(k, &ret)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return ret; } int key_to_certified(Key *k) { int r; if ((r = sshkey_to_certified(k)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } int key_drop_cert(Key *k) { int r; if ((r = sshkey_drop_cert(k)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } int key_certify(Key *k, Key *ca) { int r; if ((r = sshkey_certify(k, ca)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } int key_cert_check_authority(const Key *k, int want_host, int require_principal, const char *name, const char **reason) { int r; if ((r = sshkey_cert_check_authority(k, want_host, require_principal, name, reason)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) { int r; if ((r = sshkey_ec_validate_public(group, public)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } int key_ec_validate_private(const EC_KEY *key) { int r; if ((r = sshkey_ec_validate_private(key)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return -1; } return 0; } #endif /* WITH_OPENSSL */ void key_private_serialize(const Key *key, struct sshbuf *b) { int r; if ((r = sshkey_private_serialize(key, b)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } Key * key_private_deserialize(struct sshbuf *blob) { int r; Key *ret = NULL; if ((r = sshkey_private_deserialize(blob, &ret)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } /* authfile.c */ int key_save_private(Key *key, const char *filename, const char *passphrase, const char *comment, int force_new_format, const char *new_format_cipher, int new_format_rounds) { int r; if ((r = sshkey_save_private(key, filename, passphrase, comment, force_new_format, new_format_cipher, new_format_rounds)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return 0; } return 1; } int key_load_file(int fd, const char *filename, struct sshbuf *blob) { int r; if ((r = sshkey_load_file(fd, blob)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return 0; } return 1; } Key * key_load_cert(const char *filename) { int r; Key *ret = NULL; if ((r = sshkey_load_cert(filename, &ret)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); /* Old authfile.c ignored all file errors. */ if (r == SSH_ERR_SYSTEM_ERROR) debug("%s: %s", __func__, ssh_err(r)); else error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } Key * key_load_public(const char *filename, char **commentp) { int r; Key *ret = NULL; if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); /* Old authfile.c ignored all file errors. */ if (r == SSH_ERR_SYSTEM_ERROR) debug("%s: %s", __func__, ssh_err(r)); else error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } Key * key_load_private(const char *path, const char *passphrase, char **commentp) { int r; Key *ret = NULL; if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); /* Old authfile.c ignored all file errors. */ if (r == SSH_ERR_SYSTEM_ERROR || r == SSH_ERR_KEY_WRONG_PASSPHRASE) debug("%s: %s", __func__, ssh_err(r)); else error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } Key * key_load_private_cert(int type, const char *filename, const char *passphrase, int *perm_ok) { int r; Key *ret = NULL; if ((r = sshkey_load_private_cert(type, filename, passphrase, &ret, perm_ok)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); /* Old authfile.c ignored all file errors. */ if (r == SSH_ERR_SYSTEM_ERROR || r == SSH_ERR_KEY_WRONG_PASSPHRASE) debug("%s: %s", __func__, ssh_err(r)); else error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } Key * key_load_private_type(int type, const char *filename, const char *passphrase, char **commentp, int *perm_ok) { int r; Key *ret = NULL; if ((r = sshkey_load_private_type(type, filename, passphrase, &ret, commentp, perm_ok)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); /* Old authfile.c ignored all file errors. */ if (r == SSH_ERR_SYSTEM_ERROR || (r == SSH_ERR_KEY_WRONG_PASSPHRASE)) debug("%s: %s", __func__, ssh_err(r)); else error("%s: %s", __func__, ssh_err(r)); return NULL; } return ret; } int key_perm_ok(int fd, const char *filename) { return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; } openssh-7.2p2/key.h010064400017500001750000000100751267006270000124160ustar00djmdjm/* $OpenBSD: key.h,v 1.49 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 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 KEY_H #define KEY_H #include "sshkey.h" typedef struct sshkey Key; #define types sshkey_types #define fp_type sshkey_fp_type #define fp_rep sshkey_fp_rep #ifndef SSH_KEY_NO_DEFINE #define key_new sshkey_new #define key_free sshkey_free #define key_equal_public sshkey_equal_public #define key_equal sshkey_equal #define key_type sshkey_type #define key_cert_type sshkey_cert_type #define key_ssh_name sshkey_ssh_name #define key_ssh_name_plain sshkey_ssh_name_plain #define key_type_from_name sshkey_type_from_name #define key_ecdsa_nid_from_name sshkey_ecdsa_nid_from_name #define key_type_is_cert sshkey_type_is_cert #define key_size sshkey_size #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid #define key_is_cert sshkey_is_cert #define key_type_plain sshkey_type_plain #define key_curve_name_to_nid sshkey_curve_name_to_nid #define key_curve_nid_to_bits sshkey_curve_nid_to_bits #define key_curve_nid_to_name sshkey_curve_nid_to_name #define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg #define key_dump_ec_point sshkey_dump_ec_point #define key_dump_ec_key sshkey_dump_ec_key #endif void key_add_private(Key *); Key *key_new_private(int); void key_free(Key *); Key *key_demote(const Key *); int key_write(const Key *, FILE *); int key_read(Key *, char **); Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_to_certified(Key *); int key_drop_cert(Key *); int key_certify(Key *, Key *); void key_cert_copy(const Key *, Key *); int key_cert_check_authority(const Key *, int, int, const char *, const char **); char *key_alg_list(int, int); #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); int key_ec_validate_private(const EC_KEY *); #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ Key *key_from_blob(const u_char *, u_int); int key_to_blob(const Key *, u_char **, u_int *); int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int, const char *); int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); void key_private_serialize(const Key *, struct sshbuf *); Key *key_private_deserialize(struct sshbuf *); /* authfile.c */ int key_save_private(Key *, const char *, const char *, const char *, int, const char *, int); int key_load_file(int, const char *, struct sshbuf *); Key *key_load_cert(const char *); Key *key_load_public(const char *, char **); Key *key_load_private(const char *, const char *, char **); Key *key_load_private_cert(int, const char *, const char *, int *); Key *key_load_private_type(int, const char *, const char *, char **, int *); int key_perm_ok(int, const char *); #endif openssh-7.2p2/krl.c010064400017500001750000001036411267006270000124130ustar00djmdjm/* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* $OpenBSD: krl.c,v 1.37 2015/12/31 00:33:52 djm Exp $ */ #include "includes.h" #include /* MIN */ #include #include #include #include #include #include #include #include #include #include "sshbuf.h" #include "ssherr.h" #include "sshkey.h" #include "authfile.h" #include "misc.h" #include "log.h" #include "digest.h" #include "bitmap.h" #include "krl.h" /* #define DEBUG_KRL */ #ifdef DEBUG_KRL # define KRL_DBG(x) debug3 x #else # define KRL_DBG(x) #endif /* * Trees of revoked serial numbers, key IDs and keys. This allows * quick searching, querying and producing lists in canonical order. */ /* Tree of serial numbers. XXX make smarter: really need a real sparse bitmap */ struct revoked_serial { u_int64_t lo, hi; RB_ENTRY(revoked_serial) tree_entry; }; static int serial_cmp(struct revoked_serial *a, struct revoked_serial *b); RB_HEAD(revoked_serial_tree, revoked_serial); RB_GENERATE_STATIC(revoked_serial_tree, revoked_serial, tree_entry, serial_cmp); /* Tree of key IDs */ struct revoked_key_id { char *key_id; RB_ENTRY(revoked_key_id) tree_entry; }; static int key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b); RB_HEAD(revoked_key_id_tree, revoked_key_id); RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp); /* Tree of blobs (used for keys and fingerprints) */ struct revoked_blob { u_char *blob; size_t len; RB_ENTRY(revoked_blob) tree_entry; }; static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b); RB_HEAD(revoked_blob_tree, revoked_blob); RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp); /* Tracks revoked certs for a single CA */ struct revoked_certs { struct sshkey *ca_key; struct revoked_serial_tree revoked_serials; struct revoked_key_id_tree revoked_key_ids; TAILQ_ENTRY(revoked_certs) entry; }; TAILQ_HEAD(revoked_certs_list, revoked_certs); struct ssh_krl { u_int64_t krl_version; u_int64_t generated_date; u_int64_t flags; char *comment; struct revoked_blob_tree revoked_keys; struct revoked_blob_tree revoked_sha1s; struct revoked_certs_list revoked_certs; }; /* Return equal if a and b overlap */ static int serial_cmp(struct revoked_serial *a, struct revoked_serial *b) { if (a->hi >= b->lo && a->lo <= b->hi) return 0; return a->lo < b->lo ? -1 : 1; } static int key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b) { return strcmp(a->key_id, b->key_id); } static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b) { int r; if (a->len != b->len) { if ((r = memcmp(a->blob, b->blob, MIN(a->len, b->len))) != 0) return r; return a->len > b->len ? 1 : -1; } else return memcmp(a->blob, b->blob, a->len); } struct ssh_krl * ssh_krl_init(void) { struct ssh_krl *krl; if ((krl = calloc(1, sizeof(*krl))) == NULL) return NULL; RB_INIT(&krl->revoked_keys); RB_INIT(&krl->revoked_sha1s); TAILQ_INIT(&krl->revoked_certs); return krl; } static void revoked_certs_free(struct revoked_certs *rc) { struct revoked_serial *rs, *trs; struct revoked_key_id *rki, *trki; RB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) { RB_REMOVE(revoked_serial_tree, &rc->revoked_serials, rs); free(rs); } RB_FOREACH_SAFE(rki, revoked_key_id_tree, &rc->revoked_key_ids, trki) { RB_REMOVE(revoked_key_id_tree, &rc->revoked_key_ids, rki); free(rki->key_id); free(rki); } sshkey_free(rc->ca_key); } void ssh_krl_free(struct ssh_krl *krl) { struct revoked_blob *rb, *trb; struct revoked_certs *rc, *trc; if (krl == NULL) return; free(krl->comment); RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_keys, trb) { RB_REMOVE(revoked_blob_tree, &krl->revoked_keys, rb); free(rb->blob); free(rb); } RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_sha1s, trb) { RB_REMOVE(revoked_blob_tree, &krl->revoked_sha1s, rb); free(rb->blob); free(rb); } TAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) { TAILQ_REMOVE(&krl->revoked_certs, rc, entry); revoked_certs_free(rc); } } void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version) { krl->krl_version = version; } int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment) { free(krl->comment); if ((krl->comment = strdup(comment)) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } /* * Find the revoked_certs struct for a CA key. If allow_create is set then * create a new one in the tree if one did not exist already. */ static int revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key, struct revoked_certs **rcp, int allow_create) { struct revoked_certs *rc; int r; *rcp = NULL; TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { if ((ca_key == NULL && rc->ca_key == NULL) || sshkey_equal(rc->ca_key, ca_key)) { *rcp = rc; return 0; } } if (!allow_create) return 0; /* If this CA doesn't exist in the list then add it now */ if ((rc = calloc(1, sizeof(*rc))) == NULL) return SSH_ERR_ALLOC_FAIL; if (ca_key == NULL) rc->ca_key = NULL; else if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) { free(rc); return r; } RB_INIT(&rc->revoked_serials); RB_INIT(&rc->revoked_key_ids); TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry); KRL_DBG(("%s: new CA %s", __func__, ca_key == NULL ? "*" : sshkey_type(ca_key))); *rcp = rc; return 0; } static int insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) { struct revoked_serial rs, *ers, *crs, *irs; KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi)); memset(&rs, 0, sizeof(rs)); rs.lo = lo; rs.hi = hi; ers = RB_NFIND(revoked_serial_tree, rt, &rs); if (ers == NULL || serial_cmp(ers, &rs) != 0) { /* No entry matches. Just insert */ if ((irs = malloc(sizeof(rs))) == NULL) return SSH_ERR_ALLOC_FAIL; memcpy(irs, &rs, sizeof(*irs)); ers = RB_INSERT(revoked_serial_tree, rt, irs); if (ers != NULL) { KRL_DBG(("%s: bad: ers != NULL", __func__)); /* Shouldn't happen */ free(irs); return SSH_ERR_INTERNAL_ERROR; } ers = irs; } else { KRL_DBG(("%s: overlap found %llu:%llu", __func__, ers->lo, ers->hi)); /* * The inserted entry overlaps an existing one. Grow the * existing entry. */ if (ers->lo > lo) ers->lo = lo; if (ers->hi < hi) ers->hi = hi; } /* * The inserted or revised range might overlap or abut adjacent ones; * coalesce as necessary. */ /* Check predecessors */ while ((crs = RB_PREV(revoked_serial_tree, rt, ers)) != NULL) { KRL_DBG(("%s: pred %llu:%llu", __func__, crs->lo, crs->hi)); if (ers->lo != 0 && crs->hi < ers->lo - 1) break; /* This entry overlaps. */ if (crs->lo < ers->lo) { ers->lo = crs->lo; KRL_DBG(("%s: pred extend %llu:%llu", __func__, ers->lo, ers->hi)); } RB_REMOVE(revoked_serial_tree, rt, crs); free(crs); } /* Check successors */ while ((crs = RB_NEXT(revoked_serial_tree, rt, ers)) != NULL) { KRL_DBG(("%s: succ %llu:%llu", __func__, crs->lo, crs->hi)); if (ers->hi != (u_int64_t)-1 && crs->lo > ers->hi + 1) break; /* This entry overlaps. */ if (crs->hi > ers->hi) { ers->hi = crs->hi; KRL_DBG(("%s: succ extend %llu:%llu", __func__, ers->lo, ers->hi)); } RB_REMOVE(revoked_serial_tree, rt, crs); free(crs); } KRL_DBG(("%s: done, final %llu:%llu", __func__, ers->lo, ers->hi)); return 0; } int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key, u_int64_t serial) { return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial); } int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi) { struct revoked_certs *rc; int r; if (lo > hi || lo == 0) return SSH_ERR_INVALID_ARGUMENT; if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0) return r; return insert_serial_range(&rc->revoked_serials, lo, hi); } int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key, const char *key_id) { struct revoked_key_id *rki, *erki; struct revoked_certs *rc; int r; if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0) return r; KRL_DBG(("%s: revoke %s", __func__, key_id)); if ((rki = calloc(1, sizeof(*rki))) == NULL || (rki->key_id = strdup(key_id)) == NULL) { free(rki); return SSH_ERR_ALLOC_FAIL; } erki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki); if (erki != NULL) { free(rki->key_id); free(rki); } return 0; } /* Convert "key" to a public key blob without any certificate information */ static int plain_key_blob(const struct sshkey *key, u_char **blob, size_t *blen) { struct sshkey *kcopy; int r; if ((r = sshkey_from_private(key, &kcopy)) != 0) return r; if (sshkey_is_cert(kcopy)) { if ((r = sshkey_drop_cert(kcopy)) != 0) { sshkey_free(kcopy); return r; } } r = sshkey_to_blob(kcopy, blob, blen); sshkey_free(kcopy); return r; } /* Revoke a key blob. Ownership of blob is transferred to the tree */ static int revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, size_t len) { struct revoked_blob *rb, *erb; if ((rb = calloc(1, sizeof(*rb))) == NULL) return SSH_ERR_ALLOC_FAIL; rb->blob = blob; rb->len = len; erb = RB_INSERT(revoked_blob_tree, rbt, rb); if (erb != NULL) { free(rb->blob); free(rb); } return 0; } int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key) { u_char *blob; size_t len; int r; debug3("%s: revoke type %s", __func__, sshkey_type(key)); if ((r = plain_key_blob(key, &blob, &len)) != 0) return r; return revoke_blob(&krl->revoked_keys, blob, len); } int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) { u_char *blob; size_t len; int r; debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, &blob, &len)) != 0) return r; return revoke_blob(&krl->revoked_sha1s, blob, len); } int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key) { if (!sshkey_is_cert(key)) return ssh_krl_revoke_key_sha1(krl, key); if (key->cert->serial == 0) { return ssh_krl_revoke_cert_by_key_id(krl, key->cert->signature_key, key->cert->key_id); } else { return ssh_krl_revoke_cert_by_serial(krl, key->cert->signature_key, key->cert->serial); } } /* * Select the most compact section type to emit next in a KRL based on * the current section type, the run length of contiguous revoked serial * numbers and the gaps from the last and to the next revoked serial. * Applies a mostly-accurate bit cost model to select the section type * that will minimise the size of the resultant KRL. */ static int choose_next_state(int current_state, u_int64_t contig, int final, u_int64_t last_gap, u_int64_t next_gap, int *force_new_section) { int new_state; u_int64_t cost, cost_list, cost_range, cost_bitmap, cost_bitmap_restart; /* * Avoid unsigned overflows. * The limits are high enough to avoid confusing the calculations. */ contig = MIN(contig, 1ULL<<31); last_gap = MIN(last_gap, 1ULL<<31); next_gap = MIN(next_gap, 1ULL<<31); /* * Calculate the cost to switch from the current state to candidates. * NB. range sections only ever contain a single range, so their * switching cost is independent of the current_state. */ cost_list = cost_bitmap = cost_bitmap_restart = 0; cost_range = 8; switch (current_state) { case KRL_SECTION_CERT_SERIAL_LIST: cost_bitmap_restart = cost_bitmap = 8 + 64; break; case KRL_SECTION_CERT_SERIAL_BITMAP: cost_list = 8; cost_bitmap_restart = 8 + 64; break; case KRL_SECTION_CERT_SERIAL_RANGE: case 0: cost_bitmap_restart = cost_bitmap = 8 + 64; cost_list = 8; } /* Estimate base cost in bits of each section type */ cost_list += 64 * contig + (final ? 0 : 8+64); cost_range += (2 * 64) + (final ? 0 : 8+64); cost_bitmap += last_gap + contig + (final ? 0 : MIN(next_gap, 8+64)); cost_bitmap_restart += contig + (final ? 0 : MIN(next_gap, 8+64)); /* Convert to byte costs for actual comparison */ cost_list = (cost_list + 7) / 8; cost_bitmap = (cost_bitmap + 7) / 8; cost_bitmap_restart = (cost_bitmap_restart + 7) / 8; cost_range = (cost_range + 7) / 8; /* Now pick the best choice */ *force_new_section = 0; new_state = KRL_SECTION_CERT_SERIAL_BITMAP; cost = cost_bitmap; if (cost_range < cost) { new_state = KRL_SECTION_CERT_SERIAL_RANGE; cost = cost_range; } if (cost_list < cost) { new_state = KRL_SECTION_CERT_SERIAL_LIST; cost = cost_list; } if (cost_bitmap_restart < cost) { new_state = KRL_SECTION_CERT_SERIAL_BITMAP; *force_new_section = 1; cost = cost_bitmap_restart; } KRL_DBG(("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:" "list %llu range %llu bitmap %llu new bitmap %llu, " "selected 0x%02x%s", __func__, (long long unsigned)contig, (long long unsigned)last_gap, (long long unsigned)next_gap, final, (long long unsigned)cost_list, (long long unsigned)cost_range, (long long unsigned)cost_bitmap, (long long unsigned)cost_bitmap_restart, new_state, *force_new_section ? " restart" : "")); return new_state; } static int put_bitmap(struct sshbuf *buf, struct bitmap *bitmap) { size_t len; u_char *blob; int r; len = bitmap_nbytes(bitmap); if ((blob = malloc(len)) == NULL) return SSH_ERR_ALLOC_FAIL; if (bitmap_to_string(bitmap, blob, len) != 0) { free(blob); return SSH_ERR_INTERNAL_ERROR; } r = sshbuf_put_bignum2_bytes(buf, blob, len); free(blob); return r; } /* Generate a KRL_SECTION_CERTIFICATES KRL section */ static int revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) { int final, force_new_sect, r = SSH_ERR_INTERNAL_ERROR; u_int64_t i, contig, gap, last = 0, bitmap_start = 0; struct revoked_serial *rs, *nrs; struct revoked_key_id *rki; int next_state, state = 0; struct sshbuf *sect; struct bitmap *bitmap = NULL; if ((sect = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Store the header: optional CA scope key, reserved */ if (rc->ca_key == NULL) { if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) goto out; } else { if ((r = sshkey_puts(rc->ca_key, buf)) != 0) goto out; } if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) goto out; /* Store the revoked serials. */ for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials); rs != NULL; rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) { KRL_DBG(("%s: serial %llu:%llu state 0x%02x", __func__, (long long unsigned)rs->lo, (long long unsigned)rs->hi, state)); /* Check contiguous length and gap to next section (if any) */ nrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs); final = nrs == NULL; gap = nrs == NULL ? 0 : nrs->lo - rs->hi; contig = 1 + (rs->hi - rs->lo); /* Choose next state based on these */ next_state = choose_next_state(state, contig, final, state == 0 ? 0 : rs->lo - last, gap, &force_new_sect); /* * If the current section is a range section or has a different * type to the next section, then finish it off now. */ if (state != 0 && (force_new_sect || next_state != state || state == KRL_SECTION_CERT_SERIAL_RANGE)) { KRL_DBG(("%s: finish state 0x%02x", __func__, state)); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: if ((r = put_bitmap(sect, bitmap)) != 0) goto out; bitmap_free(bitmap); bitmap = NULL; break; } if ((r = sshbuf_put_u8(buf, state)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; sshbuf_reset(sect); } /* If we are starting a new section then prepare it now */ if (next_state != state || force_new_sect) { KRL_DBG(("%s: start state 0x%02x", __func__, next_state)); state = next_state; sshbuf_reset(sect); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: if ((bitmap = bitmap_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } bitmap_start = rs->lo; if ((r = sshbuf_put_u64(sect, bitmap_start)) != 0) goto out; break; } } /* Perform section-specific processing */ switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: for (i = 0; i < contig; i++) { if ((r = sshbuf_put_u64(sect, rs->lo + i)) != 0) goto out; } break; case KRL_SECTION_CERT_SERIAL_RANGE: if ((r = sshbuf_put_u64(sect, rs->lo)) != 0 || (r = sshbuf_put_u64(sect, rs->hi)) != 0) goto out; break; case KRL_SECTION_CERT_SERIAL_BITMAP: if (rs->lo - bitmap_start > INT_MAX) { error("%s: insane bitmap gap", __func__); goto out; } for (i = 0; i < contig; i++) { if (bitmap_set_bit(bitmap, rs->lo + i - bitmap_start) != 0) { r = SSH_ERR_ALLOC_FAIL; goto out; } } break; } last = rs->hi; } /* Flush the remaining section, if any */ if (state != 0) { KRL_DBG(("%s: serial final flush for state 0x%02x", __func__, state)); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: if ((r = put_bitmap(sect, bitmap)) != 0) goto out; bitmap_free(bitmap); bitmap = NULL; break; } if ((r = sshbuf_put_u8(buf, state)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; } KRL_DBG(("%s: serial done ", __func__)); /* Now output a section for any revocations by key ID */ sshbuf_reset(sect); RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) { KRL_DBG(("%s: key ID %s", __func__, rki->key_id)); if ((r = sshbuf_put_cstring(sect, rki->key_id)) != 0) goto out; } if (sshbuf_len(sect) != 0) { if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERT_KEY_ID)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; } r = 0; out: bitmap_free(bitmap); sshbuf_free(sect); return r; } int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, const struct sshkey **sign_keys, u_int nsign_keys) { int r = SSH_ERR_INTERNAL_ERROR; struct revoked_certs *rc; struct revoked_blob *rb; struct sshbuf *sect; u_char *sblob = NULL; size_t slen, i; if (krl->generated_date == 0) krl->generated_date = time(NULL); if ((sect = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Store the header */ if ((r = sshbuf_put(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1)) != 0 || (r = sshbuf_put_u32(buf, KRL_FORMAT_VERSION)) != 0 || (r = sshbuf_put_u64(buf, krl->krl_version)) != 0 || (r = sshbuf_put_u64(buf, krl->generated_date)) != 0 || (r = sshbuf_put_u64(buf, krl->flags)) != 0 || (r = sshbuf_put_string(buf, NULL, 0)) != 0 || (r = sshbuf_put_cstring(buf, krl->comment)) != 0) goto out; /* Store sections for revoked certificates */ TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { sshbuf_reset(sect); if ((r = revoked_certs_generate(rc, sect)) != 0) goto out; if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERTIFICATES)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; } /* Finally, output sections for revocations by public key/hash */ sshbuf_reset(sect); RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) { KRL_DBG(("%s: key len %zu ", __func__, rb->len)); if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0) goto out; } if (sshbuf_len(sect) != 0) { if ((r = sshbuf_put_u8(buf, KRL_SECTION_EXPLICIT_KEY)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; } sshbuf_reset(sect); RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) { KRL_DBG(("%s: hash len %zu ", __func__, rb->len)); if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0) goto out; } if (sshbuf_len(sect) != 0) { if ((r = sshbuf_put_u8(buf, KRL_SECTION_FINGERPRINT_SHA1)) != 0 || (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; } for (i = 0; i < nsign_keys; i++) { KRL_DBG(("%s: signature key %s", __func__, sshkey_ssh_name(sign_keys[i]))); if ((r = sshbuf_put_u8(buf, KRL_SECTION_SIGNATURE)) != 0 || (r = sshkey_puts(sign_keys[i], buf)) != 0) goto out; if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0) goto out; KRL_DBG(("%s: signature sig len %zu", __func__, slen)); if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) goto out; } r = 0; out: free(sblob); sshbuf_free(sect); return r; } static void format_timestamp(u_int64_t timestamp, char *ts, size_t nts) { time_t t; struct tm *tm; t = timestamp; tm = localtime(&t); if (tm == NULL) strlcpy(ts, "", nts); else { *ts = '\0'; strftime(ts, nts, "%Y%m%dT%H%M%S", tm); } } static int parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) { int r = SSH_ERR_INTERNAL_ERROR; u_char type; const u_char *blob; size_t blen, nbits; struct sshbuf *subsect = NULL; u_int64_t serial, serial_lo, serial_hi; struct bitmap *bitmap = NULL; char *key_id = NULL; struct sshkey *ca_key = NULL; if ((subsect = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Header: key, reserved */ if ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 || (r = sshbuf_skip_string(buf)) != 0) goto out; if (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0) goto out; while (sshbuf_len(buf) > 0) { sshbuf_free(subsect); subsect = NULL; if ((r = sshbuf_get_u8(buf, &type)) != 0 || (r = sshbuf_froms(buf, &subsect)) != 0) goto out; KRL_DBG(("%s: subsection type 0x%02x", __func__, type)); /* sshbuf_dump(subsect, stderr); */ switch (type) { case KRL_SECTION_CERT_SERIAL_LIST: while (sshbuf_len(subsect) > 0) { if ((r = sshbuf_get_u64(subsect, &serial)) != 0) goto out; if ((r = ssh_krl_revoke_cert_by_serial(krl, ca_key, serial)) != 0) goto out; } break; case KRL_SECTION_CERT_SERIAL_RANGE: if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 || (r = sshbuf_get_u64(subsect, &serial_hi)) != 0) goto out; if ((r = ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial_lo, serial_hi)) != 0) goto out; break; case KRL_SECTION_CERT_SERIAL_BITMAP: if ((bitmap = bitmap_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 || (r = sshbuf_get_bignum2_bytes_direct(subsect, &blob, &blen)) != 0) goto out; if (bitmap_from_string(bitmap, blob, blen) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } nbits = bitmap_nbits(bitmap); for (serial = 0; serial < (u_int64_t)nbits; serial++) { if (serial > 0 && serial_lo + serial == 0) { error("%s: bitmap wraps u64", __func__); r = SSH_ERR_INVALID_FORMAT; goto out; } if (!bitmap_test_bit(bitmap, serial)) continue; if ((r = ssh_krl_revoke_cert_by_serial(krl, ca_key, serial_lo + serial)) != 0) goto out; } bitmap_free(bitmap); bitmap = NULL; break; case KRL_SECTION_CERT_KEY_ID: while (sshbuf_len(subsect) > 0) { if ((r = sshbuf_get_cstring(subsect, &key_id, NULL)) != 0) goto out; if ((r = ssh_krl_revoke_cert_by_key_id(krl, ca_key, key_id)) != 0) goto out; free(key_id); key_id = NULL; } break; default: error("Unsupported KRL certificate section %u", type); r = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(subsect) > 0) { error("KRL certificate section contains unparsed data"); r = SSH_ERR_INVALID_FORMAT; goto out; } } r = 0; out: if (bitmap != NULL) bitmap_free(bitmap); free(key_id); sshkey_free(ca_key); sshbuf_free(subsect); return r; } /* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */ int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, const struct sshkey **sign_ca_keys, size_t nsign_ca_keys) { struct sshbuf *copy = NULL, *sect = NULL; struct ssh_krl *krl = NULL; char timestamp[64]; int r = SSH_ERR_INTERNAL_ERROR, sig_seen; struct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used; u_char type, *rdata = NULL; const u_char *blob; size_t i, j, sig_off, sects_off, rlen, blen, nca_used; u_int format_version; nca_used = 0; *krlp = NULL; if (sshbuf_len(buf) < sizeof(KRL_MAGIC) - 1 || memcmp(sshbuf_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) { debug3("%s: not a KRL", __func__); return SSH_ERR_KRL_BAD_MAGIC; } /* Take a copy of the KRL buffer so we can verify its signature later */ if ((copy = sshbuf_fromb(buf)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_consume(copy, sizeof(KRL_MAGIC) - 1)) != 0) goto out; if ((krl = ssh_krl_init()) == NULL) { error("%s: alloc failed", __func__); goto out; } if ((r = sshbuf_get_u32(copy, &format_version)) != 0) goto out; if (format_version != KRL_FORMAT_VERSION) { r = SSH_ERR_INVALID_FORMAT; goto out; } if ((r = sshbuf_get_u64(copy, &krl->krl_version)) != 0 || (r = sshbuf_get_u64(copy, &krl->generated_date)) != 0 || (r = sshbuf_get_u64(copy, &krl->flags)) != 0 || (r = sshbuf_skip_string(copy)) != 0 || (r = sshbuf_get_cstring(copy, &krl->comment, NULL)) != 0) goto out; format_timestamp(krl->generated_date, timestamp, sizeof(timestamp)); debug("KRL version %llu generated at %s%s%s", (long long unsigned)krl->krl_version, timestamp, *krl->comment ? ": " : "", krl->comment); /* * 1st pass: verify signatures, if any. This is done to avoid * detailed parsing of data whose provenance is unverified. */ sig_seen = 0; if (sshbuf_len(buf) < sshbuf_len(copy)) { /* Shouldn't happen */ r = SSH_ERR_INTERNAL_ERROR; goto out; } sects_off = sshbuf_len(buf) - sshbuf_len(copy); while (sshbuf_len(copy) > 0) { if ((r = sshbuf_get_u8(copy, &type)) != 0 || (r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) goto out; KRL_DBG(("%s: first pass, section 0x%02x", __func__, type)); if (type != KRL_SECTION_SIGNATURE) { if (sig_seen) { error("KRL contains non-signature section " "after signature"); r = SSH_ERR_INVALID_FORMAT; goto out; } /* Not interested for now. */ continue; } sig_seen = 1; /* First string component is the signing key */ if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(buf) < sshbuf_len(copy)) { /* Shouldn't happen */ r = SSH_ERR_INTERNAL_ERROR; goto out; } sig_off = sshbuf_len(buf) - sshbuf_len(copy); /* Second string component is the signature itself */ if ((r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* Check signature over entire KRL up to this point */ if ((r = sshkey_verify(key, blob, blen, sshbuf_ptr(buf), sig_off, 0)) != 0) goto out; /* Check if this key has already signed this KRL */ for (i = 0; i < nca_used; i++) { if (sshkey_equal(ca_used[i], key)) { error("KRL signed more than once with " "the same key"); r = SSH_ERR_INVALID_FORMAT; goto out; } } /* Record keys used to sign the KRL */ tmp_ca_used = reallocarray(ca_used, nca_used + 1, sizeof(*ca_used)); if (tmp_ca_used == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } ca_used = tmp_ca_used; ca_used[nca_used++] = key; key = NULL; } if (sshbuf_len(copy) != 0) { /* Shouldn't happen */ r = SSH_ERR_INTERNAL_ERROR; goto out; } /* * 2nd pass: parse and load the KRL, skipping the header to the point * where the section start. */ sshbuf_free(copy); if ((copy = sshbuf_fromb(buf)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_consume(copy, sects_off)) != 0) goto out; while (sshbuf_len(copy) > 0) { sshbuf_free(sect); sect = NULL; if ((r = sshbuf_get_u8(copy, &type)) != 0 || (r = sshbuf_froms(copy, §)) != 0) goto out; KRL_DBG(("%s: second pass, section 0x%02x", __func__, type)); switch (type) { case KRL_SECTION_CERTIFICATES: if ((r = parse_revoked_certs(sect, krl)) != 0) goto out; break; case KRL_SECTION_EXPLICIT_KEY: case KRL_SECTION_FINGERPRINT_SHA1: while (sshbuf_len(sect) > 0) { if ((r = sshbuf_get_string(sect, &rdata, &rlen)) != 0) goto out; if (type == KRL_SECTION_FINGERPRINT_SHA1 && rlen != 20) { error("%s: bad SHA1 length", __func__); r = SSH_ERR_INVALID_FORMAT; goto out; } if ((r = revoke_blob( type == KRL_SECTION_EXPLICIT_KEY ? &krl->revoked_keys : &krl->revoked_sha1s, rdata, rlen)) != 0) goto out; rdata = NULL; /* revoke_blob frees rdata */ } break; case KRL_SECTION_SIGNATURE: /* Handled above, but still need to stay in synch */ sshbuf_reset(sect); sect = NULL; if ((r = sshbuf_skip_string(copy)) != 0) goto out; break; default: error("Unsupported KRL section %u", type); r = SSH_ERR_INVALID_FORMAT; goto out; } if (sect != NULL && sshbuf_len(sect) > 0) { error("KRL section contains unparsed data"); r = SSH_ERR_INVALID_FORMAT; goto out; } } /* Check that the key(s) used to sign the KRL weren't revoked */ sig_seen = 0; for (i = 0; i < nca_used; i++) { if (ssh_krl_check_key(krl, ca_used[i]) == 0) sig_seen = 1; else { sshkey_free(ca_used[i]); ca_used[i] = NULL; } } if (nca_used && !sig_seen) { error("All keys used to sign KRL were revoked"); r = SSH_ERR_KEY_REVOKED; goto out; } /* If we have CA keys, then verify that one was used to sign the KRL */ if (sig_seen && nsign_ca_keys != 0) { sig_seen = 0; for (i = 0; !sig_seen && i < nsign_ca_keys; i++) { for (j = 0; j < nca_used; j++) { if (ca_used[j] == NULL) continue; if (sshkey_equal(ca_used[j], sign_ca_keys[i])) { sig_seen = 1; break; } } } if (!sig_seen) { r = SSH_ERR_SIGNATURE_INVALID; error("KRL not signed with any trusted key"); goto out; } } *krlp = krl; r = 0; out: if (r != 0) ssh_krl_free(krl); for (i = 0; i < nca_used; i++) sshkey_free(ca_used[i]); free(ca_used); free(rdata); sshkey_free(key); sshbuf_free(copy); sshbuf_free(sect); return r; } /* Checks certificate serial number and key ID revocation */ static int is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc) { struct revoked_serial rs, *ers; struct revoked_key_id rki, *erki; /* Check revocation by cert key ID */ memset(&rki, 0, sizeof(rki)); rki.key_id = key->cert->key_id; erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); if (erki != NULL) { KRL_DBG(("%s: revoked by key ID", __func__)); return SSH_ERR_KEY_REVOKED; } /* * Zero serials numbers are ignored (it's the default when the * CA doesn't specify one). */ if (key->cert->serial == 0) return 0; memset(&rs, 0, sizeof(rs)); rs.lo = rs.hi = key->cert->serial; ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); if (ers != NULL) { KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__, key->cert->serial, ers->lo, ers->hi)); return SSH_ERR_KEY_REVOKED; } return 0; } /* Checks whether a given key/cert is revoked. Does not check its CA */ static int is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) { struct revoked_blob rb, *erb; struct revoked_certs *rc; int r; /* Check explicitly revoked hashes first */ memset(&rb, 0, sizeof(rb)); if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, &rb.blob, &rb.len)) != 0) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); free(rb.blob); if (erb != NULL) { KRL_DBG(("%s: revoked by key SHA1", __func__)); return SSH_ERR_KEY_REVOKED; } /* Next, explicit keys */ memset(&rb, 0, sizeof(rb)); if ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); free(rb.blob); if (erb != NULL) { KRL_DBG(("%s: revoked by explicit key", __func__)); return SSH_ERR_KEY_REVOKED; } if (!sshkey_is_cert(key)) return 0; /* Check cert revocation for the specified CA */ if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key, &rc, 0)) != 0) return r; if (rc != NULL) { if ((r = is_cert_revoked(key, rc)) != 0) return r; } /* Check cert revocation for the wildcard CA */ if ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0) return r; if (rc != NULL) { if ((r = is_cert_revoked(key, rc)) != 0) return r; } KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); return 0; } int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key) { int r; KRL_DBG(("%s: checking key", __func__)); if ((r = is_key_revoked(krl, key)) != 0) return r; if (sshkey_is_cert(key)) { debug2("%s: checking CA key", __func__); if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0) return r; } KRL_DBG(("%s: key okay", __func__)); return 0; } int ssh_krl_file_contains_key(const char *path, const struct sshkey *key) { struct sshbuf *krlbuf = NULL; struct ssh_krl *krl = NULL; int oerrno = 0, r, fd; if (path == NULL) return 0; if ((krlbuf = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((fd = open(path, O_RDONLY)) == -1) { r = SSH_ERR_SYSTEM_ERROR; oerrno = errno; goto out; } if ((r = sshkey_load_file(fd, krlbuf)) != 0) { oerrno = errno; goto out; } if ((r = ssh_krl_from_blob(krlbuf, &krl, NULL, 0)) != 0) goto out; debug2("%s: checking KRL %s", __func__, path); r = ssh_krl_check_key(krl, key); out: close(fd); sshbuf_free(krlbuf); ssh_krl_free(krl); if (r != 0) errno = oerrno; return r; } openssh-7.2p2/krl.h010064400017500001750000000050601267006270000124140ustar00djmdjm/* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* $OpenBSD: krl.h,v 1.5 2015/12/30 23:46:14 djm Exp $ */ #ifndef _KRL_H #define _KRL_H /* Functions to manage key revocation lists */ #define KRL_MAGIC "SSHKRL\n\0" #define KRL_FORMAT_VERSION 1 /* KRL section types */ #define KRL_SECTION_CERTIFICATES 1 #define KRL_SECTION_EXPLICIT_KEY 2 #define KRL_SECTION_FINGERPRINT_SHA1 3 #define KRL_SECTION_SIGNATURE 4 /* KRL_SECTION_CERTIFICATES subsection types */ #define KRL_SECTION_CERT_SERIAL_LIST 0x20 #define KRL_SECTION_CERT_SERIAL_RANGE 0x21 #define KRL_SECTION_CERT_SERIAL_BITMAP 0x22 #define KRL_SECTION_CERT_KEY_ID 0x23 struct sshkey; struct sshbuf; struct ssh_krl; struct ssh_krl *ssh_krl_init(void); void ssh_krl_free(struct ssh_krl *krl); void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version); int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment); int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key, u_int64_t serial); int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi); int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key, const char *key_id); int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key); int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key); int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key); int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, const struct sshkey **sign_keys, u_int nsign_keys); int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key); int ssh_krl_file_contains_key(const char *path, const struct sshkey *key); #endif /* _KRL_H */ openssh-7.2p2/log.c010064400017500001750000000246301267006270000124040ustar00djmdjm/* $OpenBSD: log.c,v 1.46 2015/07/08 19:04:21 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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. */ #include "includes.h" #include #include #include #include #include #include #include #include #include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif #include "log.h" static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 1; static int log_stderr_fd = STDERR_FILENO; static int log_facility = LOG_AUTH; static char *argv0; static log_handler_fn *log_handler; static void *log_handler_ctx; extern char *__progname; #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) /* textual representation of log-facilities/levels */ static struct { const char *name; SyslogFacility val; } log_facilities[] = { { "DAEMON", SYSLOG_FACILITY_DAEMON }, { "USER", SYSLOG_FACILITY_USER }, { "AUTH", SYSLOG_FACILITY_AUTH }, #ifdef LOG_AUTHPRIV { "AUTHPRIV", SYSLOG_FACILITY_AUTHPRIV }, #endif { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, { NULL, SYSLOG_FACILITY_NOT_SET } }; static struct { const char *name; LogLevel val; } log_levels[] = { { "QUIET", SYSLOG_LEVEL_QUIET }, { "FATAL", SYSLOG_LEVEL_FATAL }, { "ERROR", SYSLOG_LEVEL_ERROR }, { "INFO", SYSLOG_LEVEL_INFO }, { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, { NULL, SYSLOG_LEVEL_NOT_SET } }; SyslogFacility log_facility_number(char *name) { int i; if (name != NULL) for (i = 0; log_facilities[i].name; i++) if (strcasecmp(log_facilities[i].name, name) == 0) return log_facilities[i].val; return SYSLOG_FACILITY_NOT_SET; } const char * log_facility_name(SyslogFacility facility) { u_int i; for (i = 0; log_facilities[i].name; i++) if (log_facilities[i].val == facility) return log_facilities[i].name; return NULL; } LogLevel log_level_number(char *name) { int i; if (name != NULL) for (i = 0; log_levels[i].name; i++) if (strcasecmp(log_levels[i].name, name) == 0) return log_levels[i].val; return SYSLOG_LEVEL_NOT_SET; } const char * log_level_name(LogLevel level) { u_int i; for (i = 0; log_levels[i].name != NULL; i++) if (log_levels[i].val == level) return log_levels[i].name; return NULL; } /* Error messages that should be logged. */ void error(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_ERROR, fmt, args); va_end(args); } void sigdie(const char *fmt,...) { #ifdef DO_LOG_SAFE_IN_SIGHAND va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_FATAL, fmt, args); va_end(args); #endif _exit(1); } /* Log this message (information that usually should go to the log). */ void logit(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_INFO, fmt, args); va_end(args); } /* More detailed messages (information that does not need to go to the log). */ void verbose(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); va_end(args); } /* Debugging messages that should not be logged during normal operation. */ void debug(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); va_end(args); } void debug2(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); va_end(args); } void debug3(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); va_end(args); } /* * Initialize the log. */ void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif argv0 = av0; switch (level) { case SYSLOG_LEVEL_QUIET: case SYSLOG_LEVEL_FATAL: case SYSLOG_LEVEL_ERROR: case SYSLOG_LEVEL_INFO: case SYSLOG_LEVEL_VERBOSE: case SYSLOG_LEVEL_DEBUG1: case SYSLOG_LEVEL_DEBUG2: case SYSLOG_LEVEL_DEBUG3: log_level = level; break; default: fprintf(stderr, "Unrecognized internal syslog level code %d\n", (int) level); exit(1); } log_handler = NULL; log_handler_ctx = NULL; log_on_stderr = on_stderr; if (on_stderr) return; switch (facility) { case SYSLOG_FACILITY_DAEMON: log_facility = LOG_DAEMON; break; case SYSLOG_FACILITY_USER: log_facility = LOG_USER; break; case SYSLOG_FACILITY_AUTH: log_facility = LOG_AUTH; break; #ifdef LOG_AUTHPRIV case SYSLOG_FACILITY_AUTHPRIV: log_facility = LOG_AUTHPRIV; break; #endif case SYSLOG_FACILITY_LOCAL0: log_facility = LOG_LOCAL0; break; case SYSLOG_FACILITY_LOCAL1: log_facility = LOG_LOCAL1; break; case SYSLOG_FACILITY_LOCAL2: log_facility = LOG_LOCAL2; break; case SYSLOG_FACILITY_LOCAL3: log_facility = LOG_LOCAL3; break; case SYSLOG_FACILITY_LOCAL4: log_facility = LOG_LOCAL4; break; case SYSLOG_FACILITY_LOCAL5: log_facility = LOG_LOCAL5; break; case SYSLOG_FACILITY_LOCAL6: log_facility = LOG_LOCAL6; break; case SYSLOG_FACILITY_LOCAL7: log_facility = LOG_LOCAL7; break; default: fprintf(stderr, "Unrecognized internal syslog facility code %d\n", (int) facility); exit(1); } /* * If an external library (eg libwrap) attempts to use syslog * immediately after reexec, syslog may be pointing to the wrong * facility, so we force an open/close of syslog here. */ #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); closelog_r(&sdata); #else openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); closelog(); #endif } void log_change_level(LogLevel new_log_level) { /* no-op if log_init has not been called */ if (argv0 == NULL) return; log_init(argv0, new_log_level, log_facility, log_on_stderr); } int log_is_on_stderr(void) { return log_on_stderr; } /* redirect what would usually get written to stderr to specified file */ void log_redirect_stderr_to(const char *logfile) { int fd; if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) { fprintf(stderr, "Couldn't open logfile %s: %s\n", logfile, strerror(errno)); exit(1); } log_stderr_fd = fd; } #define MSGBUFSIZ 1024 void set_log_handler(log_handler_fn *handler, void *ctx) { log_handler = handler; log_handler_ctx = ctx; } void do_log2(LogLevel level, const char *fmt,...) { va_list args; va_start(args, fmt); do_log(level, fmt, args); va_end(args); } void do_log(LogLevel level, const char *fmt, va_list args) { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif char msgbuf[MSGBUFSIZ]; char fmtbuf[MSGBUFSIZ]; char *txt = NULL; int pri = LOG_INFO; int saved_errno = errno; log_handler_fn *tmp_handler; if (level > log_level) return; switch (level) { case SYSLOG_LEVEL_FATAL: if (!log_on_stderr) txt = "fatal"; pri = LOG_CRIT; break; case SYSLOG_LEVEL_ERROR: if (!log_on_stderr) txt = "error"; pri = LOG_ERR; break; case SYSLOG_LEVEL_INFO: pri = LOG_INFO; break; case SYSLOG_LEVEL_VERBOSE: pri = LOG_INFO; break; case SYSLOG_LEVEL_DEBUG1: txt = "debug1"; pri = LOG_DEBUG; break; case SYSLOG_LEVEL_DEBUG2: txt = "debug2"; pri = LOG_DEBUG; break; case SYSLOG_LEVEL_DEBUG3: txt = "debug3"; pri = LOG_DEBUG; break; default: txt = "internal error"; pri = LOG_ERR; break; } if (txt != NULL && log_handler == NULL) { snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); } else { vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); } strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS); if (log_handler != NULL) { /* Avoid recursion */ tmp_handler = log_handler; log_handler = NULL; tmp_handler(level, fmtbuf, log_handler_ctx); log_handler = tmp_handler; } else if (log_on_stderr) { snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); (void)write(log_stderr_fd, msgbuf, strlen(msgbuf)); } else { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); syslog_r(pri, &sdata, "%.500s", fmtbuf); closelog_r(&sdata); #else openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); syslog(pri, "%.500s", fmtbuf); closelog(); #endif } errno = saved_errno; } openssh-7.2p2/log.h010064400017500001750000000050161267006270000124060ustar00djmdjm/* $OpenBSD: log.h,v 1.20 2013/04/07 02:10:33 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 SSH_LOG_H #define SSH_LOG_H /* Supported syslog facilities and levels. */ typedef enum { SYSLOG_FACILITY_DAEMON, SYSLOG_FACILITY_USER, SYSLOG_FACILITY_AUTH, #ifdef LOG_AUTHPRIV SYSLOG_FACILITY_AUTHPRIV, #endif SYSLOG_FACILITY_LOCAL0, SYSLOG_FACILITY_LOCAL1, SYSLOG_FACILITY_LOCAL2, SYSLOG_FACILITY_LOCAL3, SYSLOG_FACILITY_LOCAL4, SYSLOG_FACILITY_LOCAL5, SYSLOG_FACILITY_LOCAL6, SYSLOG_FACILITY_LOCAL7, SYSLOG_FACILITY_NOT_SET = -1 } SyslogFacility; typedef enum { SYSLOG_LEVEL_QUIET, SYSLOG_LEVEL_FATAL, SYSLOG_LEVEL_ERROR, SYSLOG_LEVEL_INFO, SYSLOG_LEVEL_VERBOSE, SYSLOG_LEVEL_DEBUG1, SYSLOG_LEVEL_DEBUG2, SYSLOG_LEVEL_DEBUG3, SYSLOG_LEVEL_NOT_SET = -1 } LogLevel; typedef void (log_handler_fn)(LogLevel, const char *, void *); void log_init(char *, LogLevel, SyslogFacility, int); void log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); SyslogFacility log_facility_number(char *); const char * log_facility_name(SyslogFacility); LogLevel log_level_number(char *); const char * log_level_name(LogLevel); void fatal(const char *, ...) __attribute__((noreturn)) __attribute__((format(printf, 1, 2))); void error(const char *, ...) __attribute__((format(printf, 1, 2))); void sigdie(const char *, ...) __attribute__((noreturn)) __attribute__((format(printf, 1, 2))); void logit(const char *, ...) __attribute__((format(printf, 1, 2))); void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); void debug(const char *, ...) __attribute__((format(printf, 1, 2))); void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); void set_log_handler(log_handler_fn *, void *); void do_log2(LogLevel, const char *, ...) __attribute__((format(printf, 2, 3))); void do_log(LogLevel, const char *, va_list); void cleanup_exit(int) __attribute__((noreturn)); #endif openssh-7.2p2/loginrec.c010064400017500001750000001237521267006270000134320ustar00djmdjm/* * Copyright (c) 2000 Andre Lucas. All rights reserved. * Portions copyright (c) 1998 Todd C. Miller * Portions copyright (c) 1996 Jason Downs * Portions copyright (c) 1996 Theo de Raadt * * 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. */ /* * The btmp logging code is derived from login.c from util-linux and is under * the the following license: * * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /** ** loginrec.c: platform-independent login recording and lastlog retrieval **/ /* * The new login code explained * ============================ * * This code attempts to provide a common interface to login recording * (utmp and friends) and last login time retrieval. * * Its primary means of achieving this is to use 'struct logininfo', a * union of all the useful fields in the various different types of * system login record structures one finds on UNIX variants. * * We depend on autoconf to define which recording methods are to be * used, and which fields are contained in the relevant data structures * on the local system. Many C preprocessor symbols affect which code * gets compiled here. * * The code is designed to make it easy to modify a particular * recording method, without affecting other methods nor requiring so * many nested conditional compilation blocks as were commonplace in * the old code. * * For login recording, we try to use the local system's libraries as * these are clearly most likely to work correctly. For utmp systems * this usually means login() and logout() or setutent() etc., probably * in libutil, along with logwtmp() etc. On these systems, we fall back * to writing the files directly if we have to, though this method * requires very thorough testing so we do not corrupt local auditing * information. These files and their access methods are very system * specific indeed. * * For utmpx systems, the corresponding library functions are * setutxent() etc. To the author's knowledge, all utmpx systems have * these library functions and so no direct write is attempted. If such * a system exists and needs support, direct analogues of the [uw]tmp * code should suffice. * * Retrieving the time of last login ('lastlog') is in some ways even * more problemmatic than login recording. Some systems provide a * simple table of all users which we seek based on uid and retrieve a * relatively standard structure. Others record the same information in * a directory with a separate file, and others don't record the * information separately at all. For systems in the latter category, * we look backwards in the wtmp or wtmpx file for the last login entry * for our user. Naturally this is slower and on busy systems could * incur a significant performance penalty. * * Calling the new code * -------------------- * * In OpenSSH all login recording and retrieval is performed in * login.c. Here you'll find working examples. Also, in the logintest.c * program there are more examples. * * Internal handler calling method * ------------------------------- * * When a call is made to login_login() or login_logout(), both * routines set a struct logininfo flag defining which action (log in, * or log out) is to be taken. They both then call login_write(), which * calls whichever of the many structure-specific handlers autoconf * selects for the local system. * * The handlers themselves handle system data structure specifics. Both * struct utmp and struct utmpx have utility functions (see * construct_utmp*()) to try to make it simpler to add extra systems * that introduce new features to either structure. * * While it may seem terribly wasteful to replicate so much similar * code for each method, experience has shown that maintaining code to * write both struct utmp and utmpx in one function, whilst maintaining * support for all systems whether they have library support or not, is * a difficult and time-consuming task. * * Lastlog support proceeds similarly. Functions login_get_lastlog() * (and its OpenSSH-tuned friend login_get_lastlog_time()) call * getlast_entry(), which tries one of three methods to find the last * login time. It uses local system lastlog support if it can, * otherwise it tries wtmp or wtmpx before giving up and returning 0, * meaning "tilt". * * Maintenance * ----------- * * In many cases it's possible to tweak autoconf to select the correct * methods for a particular platform, either by improving the detection * code (best), or by presetting DISABLE_ or CONF__FILE * symbols for the platform. * * Use logintest to check which symbols are defined before modifying * configure.ac and loginrec.c. (You have to build logintest yourself * with 'make logintest' as it's not built by default.) * * Otherwise, patches to the specific method(s) are very helpful! */ #include "includes.h" #include #include #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "ssh.h" #include "loginrec.h" #include "log.h" #include "atomicio.h" #include "packet.h" #include "canohost.h" #include "auth.h" #include "buffer.h" #ifdef HAVE_UTIL_H # include #endif /** ** prototypes for helper functions in this file **/ #if HAVE_UTMP_H void set_utmp_time(struct logininfo *li, struct utmp *ut); void construct_utmp(struct logininfo *li, struct utmp *ut); #endif #ifdef HAVE_UTMPX_H void set_utmpx_time(struct logininfo *li, struct utmpx *ut); void construct_utmpx(struct logininfo *li, struct utmpx *ut); #endif int utmp_write_entry(struct logininfo *li); int utmpx_write_entry(struct logininfo *li); int wtmp_write_entry(struct logininfo *li); int wtmpx_write_entry(struct logininfo *li); int lastlog_write_entry(struct logininfo *li); int syslogin_write_entry(struct logininfo *li); int getlast_entry(struct logininfo *li); int lastlog_get_entry(struct logininfo *li); int utmpx_get_entry(struct logininfo *li); int wtmp_get_entry(struct logininfo *li); int wtmpx_get_entry(struct logininfo *li); extern Buffer loginmsg; /* pick the shortest string */ #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) /** ** platform-independent login functions **/ /* * login_login(struct logininfo *) - Record a login * * Call with a pointer to a struct logininfo initialised with * login_init_entry() or login_alloc_entry() * * Returns: * >0 if successful * 0 on failure (will use OpenSSH's logging facilities for diagnostics) */ int login_login(struct logininfo *li) { li->type = LTYPE_LOGIN; return (login_write(li)); } /* * login_logout(struct logininfo *) - Record a logout * * Call as with login_login() * * Returns: * >0 if successful * 0 on failure (will use OpenSSH's logging facilities for diagnostics) */ int login_logout(struct logininfo *li) { li->type = LTYPE_LOGOUT; return (login_write(li)); } /* * login_get_lastlog_time(int) - Retrieve the last login time * * Retrieve the last login time for the given uid. Will try to use the * system lastlog facilities if they are available, but will fall back * to looking in wtmp/wtmpx if necessary * * Returns: * 0 on failure, or if user has never logged in * Time in seconds from the epoch if successful * * Useful preprocessor symbols: * DISABLE_LASTLOG: If set, *never* even try to retrieve lastlog * info * USE_LASTLOG: If set, indicates the presence of system lastlog * facilities. If this and DISABLE_LASTLOG are not set, * try to retrieve lastlog information from wtmp/wtmpx. */ unsigned int login_get_lastlog_time(const uid_t uid) { struct logininfo li; if (login_get_lastlog(&li, uid)) return (li.tv_sec); else return (0); } /* * login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry * * Retrieve a logininfo structure populated (only partially) with * information from the system lastlog data, or from wtmp/wtmpx if no * system lastlog information exists. * * Note this routine must be given a pre-allocated logininfo. * * Returns: * >0: A pointer to your struct logininfo if successful * 0 on failure (will use OpenSSH's logging facilities for diagnostics) */ struct logininfo * login_get_lastlog(struct logininfo *li, const uid_t uid) { struct passwd *pw; memset(li, '\0', sizeof(*li)); li->uid = uid; /* * If we don't have a 'real' lastlog, we need the username to * reliably search wtmp(x) for the last login (see * wtmp_get_entry().) */ pw = getpwuid(uid); if (pw == NULL) fatal("%s: Cannot find account for uid %ld", __func__, (long)uid); if (strlcpy(li->username, pw->pw_name, sizeof(li->username)) >= sizeof(li->username)) { error("%s: username too long (%lu > max %lu)", __func__, (unsigned long)strlen(pw->pw_name), (unsigned long)sizeof(li->username) - 1); return NULL; } if (getlast_entry(li)) return (li); else return (NULL); } /* * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise * a logininfo structure * * This function creates a new struct logininfo, a data structure * meant to carry the information required to portably record login info. * * Returns a pointer to a newly created struct logininfo. If memory * allocation fails, the program halts. */ struct logininfo *login_alloc_entry(pid_t pid, const char *username, const char *hostname, const char *line) { struct logininfo *newli; newli = xmalloc(sizeof(*newli)); login_init_entry(newli, pid, username, hostname, line); return (newli); } /* login_free_entry(struct logininfo *) - free struct memory */ void login_free_entry(struct logininfo *li) { free(li); } /* login_init_entry(struct logininfo *, int, char*, char*, char*) * - initialise a struct logininfo * * Populates a new struct logininfo, a data structure meant to carry * the information required to portably record login info. * * Returns: 1 */ int login_init_entry(struct logininfo *li, pid_t pid, const char *username, const char *hostname, const char *line) { struct passwd *pw; memset(li, 0, sizeof(*li)); li->pid = pid; /* set the line information */ if (line) line_fullname(li->line, line, sizeof(li->line)); if (username) { strlcpy(li->username, username, sizeof(li->username)); pw = getpwnam(li->username); if (pw == NULL) { fatal("%s: Cannot find user \"%s\"", __func__, li->username); } li->uid = pw->pw_uid; } if (hostname) strlcpy(li->hostname, hostname, sizeof(li->hostname)); return (1); } /* * login_set_current_time(struct logininfo *) - set the current time * * Set the current time in a logininfo structure. This function is * meant to eliminate the need to deal with system dependencies for * time handling. */ void login_set_current_time(struct logininfo *li) { struct timeval tv; gettimeofday(&tv, NULL); li->tv_sec = tv.tv_sec; li->tv_usec = tv.tv_usec; } /* copy a sockaddr_* into our logininfo */ void login_set_addr(struct logininfo *li, const struct sockaddr *sa, const unsigned int sa_size) { unsigned int bufsize = sa_size; /* make sure we don't overrun our union */ if (sizeof(li->hostaddr) < sa_size) bufsize = sizeof(li->hostaddr); memcpy(&li->hostaddr.sa, sa, bufsize); } /** ** login_write: Call low-level recording functions based on autoconf ** results **/ int login_write(struct logininfo *li) { #ifndef HAVE_CYGWIN if (geteuid() != 0) { logit("Attempt to write login records by non-root user (aborting)"); return (1); } #endif /* set the timestamp */ login_set_current_time(li); #ifdef USE_LOGIN syslogin_write_entry(li); #endif #ifdef USE_LASTLOG if (li->type == LTYPE_LOGIN) lastlog_write_entry(li); #endif #ifdef USE_UTMP utmp_write_entry(li); #endif #ifdef USE_WTMP wtmp_write_entry(li); #endif #ifdef USE_UTMPX utmpx_write_entry(li); #endif #ifdef USE_WTMPX wtmpx_write_entry(li); #endif #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line, &loginmsg)) logit("Writing login record failed for %s", li->username); #endif #ifdef SSH_AUDIT_EVENTS if (li->type == LTYPE_LOGIN) audit_session_open(li); else if (li->type == LTYPE_LOGOUT) audit_session_close(li); #endif return (0); } #ifdef LOGIN_NEEDS_UTMPX int login_utmp_only(struct logininfo *li) { li->type = LTYPE_LOGIN; login_set_current_time(li); # ifdef USE_UTMP utmp_write_entry(li); # endif # ifdef USE_WTMP wtmp_write_entry(li); # endif # ifdef USE_UTMPX utmpx_write_entry(li); # endif # ifdef USE_WTMPX wtmpx_write_entry(li); # endif return (0); } #endif /** ** getlast_entry: Call low-level functions to retrieve the last login ** time. **/ /* take the uid in li and return the last login time */ int getlast_entry(struct logininfo *li) { #ifdef USE_LASTLOG return(lastlog_get_entry(li)); #else /* !USE_LASTLOG */ #if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \ defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER) return (utmpx_get_entry(li)); #endif #if defined(DISABLE_LASTLOG) /* On some systems we shouldn't even try to obtain last login * time, e.g. AIX */ return (0); # elif defined(USE_WTMP) && \ (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) /* retrieve last login time from utmp */ return (wtmp_get_entry(li)); # elif defined(USE_WTMPX) && \ (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) /* If wtmp isn't available, try wtmpx */ return (wtmpx_get_entry(li)); # else /* Give up: No means of retrieving last login time */ return (0); # endif /* DISABLE_LASTLOG */ #endif /* USE_LASTLOG */ } /* * 'line' string utility functions * * These functions process the 'line' string into one of three forms: * * 1. The full filename (including '/dev') * 2. The stripped name (excluding '/dev') * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 * /dev/pts/1 -> ts/1 ) * * Form 3 is used on some systems to identify a .tmp.? entry when * attempting to remove it. Typically both addition and removal is * performed by one application - say, sshd - so as long as the choice * uniquely identifies a terminal it's ok. */ /* * line_fullname(): add the leading '/dev/' if it doesn't exist make * sure dst has enough space, if not just copy src (ugh) */ char * line_fullname(char *dst, const char *src, u_int dstsize) { memset(dst, '\0', dstsize); if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) strlcpy(dst, src, dstsize); else { strlcpy(dst, "/dev/", dstsize); strlcat(dst, src, dstsize); } return (dst); } /* line_stripname(): strip the leading '/dev' if it exists, return dst */ char * line_stripname(char *dst, const char *src, int dstsize) { memset(dst, '\0', dstsize); if (strncmp(src, "/dev/", 5) == 0) strlcpy(dst, src + 5, dstsize); else strlcpy(dst, src, dstsize); return (dst); } /* * line_abbrevname(): Return the abbreviated (usually four-character) * form of the line (Just use the last characters of the * full name.) * * NOTE: use strncpy because we do NOT necessarily want zero * termination */ char * line_abbrevname(char *dst, const char *src, int dstsize) { size_t len; memset(dst, '\0', dstsize); /* Always skip prefix if present */ if (strncmp(src, "/dev/", 5) == 0) src += 5; #ifdef WITH_ABBREV_NO_TTY if (strncmp(src, "tty", 3) == 0) src += 3; #endif len = strlen(src); if (len > 0) { if (((int)len - dstsize) > 0) src += ((int)len - dstsize); /* note: _don't_ change this to strlcpy */ strncpy(dst, src, (size_t)dstsize); } return (dst); } /** ** utmp utility functions ** ** These functions manipulate struct utmp, taking system differences ** into account. **/ #if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) /* build the utmp structure */ void set_utmp_time(struct logininfo *li, struct utmp *ut) { # if defined(HAVE_TV_IN_UTMP) ut->ut_tv.tv_sec = li->tv_sec; ut->ut_tv.tv_usec = li->tv_usec; # elif defined(HAVE_TIME_IN_UTMP) ut->ut_time = li->tv_sec; # endif } void construct_utmp(struct logininfo *li, struct utmp *ut) { # ifdef HAVE_ADDR_V6_IN_UTMP struct sockaddr_in6 *sa6; # endif memset(ut, '\0', sizeof(*ut)); /* First fill out fields used for both logins and logouts */ # ifdef HAVE_ID_IN_UTMP line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id)); # endif # ifdef HAVE_TYPE_IN_UTMP /* This is done here to keep utmp constants out of struct logininfo */ switch (li->type) { case LTYPE_LOGIN: ut->ut_type = USER_PROCESS; #ifdef _UNICOS cray_set_tmpdir(ut); #endif break; case LTYPE_LOGOUT: ut->ut_type = DEAD_PROCESS; #ifdef _UNICOS cray_retain_utmp(ut, li->pid); #endif break; } # endif set_utmp_time(li, ut); line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line)); # ifdef HAVE_PID_IN_UTMP ut->ut_pid = li->pid; # endif /* If we're logging out, leave all other fields blank */ if (li->type == LTYPE_LOGOUT) return; /* * These fields are only used when logging in, and are blank * for logouts. */ /* Use strncpy because we don't necessarily want null termination */ strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); # ifdef HAVE_HOST_IN_UTMP strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); # endif # ifdef HAVE_ADDR_IN_UTMP /* this is just a 32-bit IP address */ if (li->hostaddr.sa.sa_family == AF_INET) ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; # endif # ifdef HAVE_ADDR_V6_IN_UTMP /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; ut->ut_addr_v6[1] = 0; ut->ut_addr_v6[2] = 0; ut->ut_addr_v6[3] = 0; } } # endif } #endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ /** ** utmpx utility functions ** ** These functions manipulate struct utmpx, accounting for system ** variations. **/ #if defined(USE_UTMPX) || defined (USE_WTMPX) /* build the utmpx structure */ void set_utmpx_time(struct logininfo *li, struct utmpx *utx) { # if defined(HAVE_TV_IN_UTMPX) utx->ut_tv.tv_sec = li->tv_sec; utx->ut_tv.tv_usec = li->tv_usec; # elif defined(HAVE_TIME_IN_UTMPX) utx->ut_time = li->tv_sec; # endif } void construct_utmpx(struct logininfo *li, struct utmpx *utx) { # ifdef HAVE_ADDR_V6_IN_UTMP struct sockaddr_in6 *sa6; # endif memset(utx, '\0', sizeof(*utx)); # ifdef HAVE_ID_IN_UTMPX line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); # endif /* this is done here to keep utmp constants out of loginrec.h */ switch (li->type) { case LTYPE_LOGIN: utx->ut_type = USER_PROCESS; break; case LTYPE_LOGOUT: utx->ut_type = DEAD_PROCESS; break; } line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); set_utmpx_time(li, utx); utx->ut_pid = li->pid; /* strncpy(): Don't necessarily want null termination */ strncpy(utx->ut_user, li->username, MIN_SIZEOF(utx->ut_user, li->username)); if (li->type == LTYPE_LOGOUT) return; /* * These fields are only used when logging in, and are blank * for logouts. */ # ifdef HAVE_HOST_IN_UTMPX strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); # endif # ifdef HAVE_ADDR_IN_UTMPX /* this is just a 32-bit IP address */ if (li->hostaddr.sa.sa_family == AF_INET) utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; # endif # ifdef HAVE_ADDR_V6_IN_UTMP /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); memcpy(utx->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { utx->ut_addr_v6[0] = utx->ut_addr_v6[3]; utx->ut_addr_v6[1] = 0; utx->ut_addr_v6[2] = 0; utx->ut_addr_v6[3] = 0; } } # endif # ifdef HAVE_SYSLEN_IN_UTMPX /* ut_syslen is the length of the utx_host string */ utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host)); # endif } #endif /* USE_UTMPX || USE_WTMPX */ /** ** Low-level utmp functions **/ /* FIXME: (ATL) utmp_write_direct needs testing */ #ifdef USE_UTMP /* if we can, use pututline() etc. */ # if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \ defined(HAVE_PUTUTLINE) # define UTMP_USE_LIBRARY # endif /* write a utmp entry with the system's help (pututline() and pals) */ # ifdef UTMP_USE_LIBRARY static int utmp_write_library(struct logininfo *li, struct utmp *ut) { setutent(); pututline(ut); # ifdef HAVE_ENDUTENT endutent(); # endif return (1); } # else /* UTMP_USE_LIBRARY */ /* * Write a utmp entry direct to the file * This is a slightly modification of code in OpenBSD's login.c */ static int utmp_write_direct(struct logininfo *li, struct utmp *ut) { struct utmp old_ut; register int fd; int tty; /* FIXME: (ATL) ttyslot() needs local implementation */ #if defined(HAVE_GETTTYENT) struct ttyent *ty; tty=0; setttyent(); while (NULL != (ty = getttyent())) { tty++; if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) break; } endttyent(); if (NULL == ty) { logit("%s: tty not found", __func__); return (0); } #else /* FIXME */ tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ #endif /* HAVE_GETTTYENT */ if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { off_t pos, ret; pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); close(fd); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); close(fd); return (0); } /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not * and ut_line and ut_name match, preserve the old ut_line. */ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); close(fd); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); close(fd); return (0); } if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { logit("%s: error writing %s: %s", __func__, UTMP_FILE, strerror(errno)); close(fd); return (0); } close(fd); return (1); } else { return (0); } } # endif /* UTMP_USE_LIBRARY */ static int utmp_perform_login(struct logininfo *li) { struct utmp ut; construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmp_write_direct(li, &ut)) { logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif return (1); } static int utmp_perform_logout(struct logininfo *li) { struct utmp ut; construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmp_write_direct(li, &ut)) { logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif return (1); } int utmp_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return (utmp_perform_login(li)); case LTYPE_LOGOUT: return (utmp_perform_logout(li)); default: logit("%s: invalid type field", __func__); return (0); } } #endif /* USE_UTMP */ /** ** Low-level utmpx functions **/ /* not much point if we don't want utmpx entries */ #ifdef USE_UTMPX /* if we have the wherewithall, use pututxline etc. */ # if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ defined(HAVE_PUTUTXLINE) # define UTMPX_USE_LIBRARY # endif /* write a utmpx entry with the system's help (pututxline() and pals) */ # ifdef UTMPX_USE_LIBRARY static int utmpx_write_library(struct logininfo *li, struct utmpx *utx) { setutxent(); pututxline(utx); # ifdef HAVE_ENDUTXENT endutxent(); # endif return (1); } # else /* UTMPX_USE_LIBRARY */ /* write a utmp entry direct to the file */ static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { logit("%s: not implemented!", __func__); return (0); } # endif /* UTMPX_USE_LIBRARY */ static int utmpx_perform_login(struct logininfo *li) { struct utmpx utx; construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { logit("%s: utmp_write_library() failed", __func__); return (0); } # else if (!utmpx_write_direct(li, &ut)) { logit("%s: utmp_write_direct() failed", __func__); return (0); } # endif return (1); } static int utmpx_perform_logout(struct logininfo *li) { struct utmpx utx; construct_utmpx(li, &utx); # ifdef HAVE_ID_IN_UTMPX line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id)); # endif # ifdef HAVE_TYPE_IN_UTMPX utx.ut_type = DEAD_PROCESS; # endif # ifdef UTMPX_USE_LIBRARY utmpx_write_library(li, &utx); # else utmpx_write_direct(li, &utx); # endif return (1); } int utmpx_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return (utmpx_perform_login(li)); case LTYPE_LOGOUT: return (utmpx_perform_logout(li)); default: logit("%s: invalid type field", __func__); return (0); } } #endif /* USE_UTMPX */ /** ** Low-level wtmp functions **/ #ifdef USE_WTMP /* * Write a wtmp entry direct to the end of the file * This is a slight modification of code in OpenBSD's logwtmp.c */ static int wtmp_write(struct logininfo *li, struct utmp *ut) { struct stat buf; int fd, ret = 1; if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { logit("%s: problem writing %s: %s", __func__, WTMP_FILE, strerror(errno)); return (0); } if (fstat(fd, &buf) == 0) if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { ftruncate(fd, buf.st_size); logit("%s: problem writing %s: %s", __func__, WTMP_FILE, strerror(errno)); ret = 0; } close(fd); return (ret); } static int wtmp_perform_login(struct logininfo *li) { struct utmp ut; construct_utmp(li, &ut); return (wtmp_write(li, &ut)); } static int wtmp_perform_logout(struct logininfo *li) { struct utmp ut; construct_utmp(li, &ut); return (wtmp_write(li, &ut)); } int wtmp_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return (wtmp_perform_login(li)); case LTYPE_LOGOUT: return (wtmp_perform_logout(li)); default: logit("%s: invalid type field", __func__); return (0); } } /* * Notes on fetching login data from wtmp/wtmpx * * Logouts are usually recorded with (amongst other things) a blank * username on a given tty line. However, some systems (HP-UX is one) * leave all fields set, but change the ut_type field to DEAD_PROCESS. * * Since we're only looking for logins here, we know that the username * must be set correctly. On systems that leave it in, we check for * ut_type==USER_PROCESS (indicating a login.) * * Portability: Some systems may set something other than USER_PROCESS * to indicate a login process. I don't know of any as I write. Also, * it's possible that some systems may both leave the username in * place and not have ut_type. */ /* return true if this wtmp entry indicates a login */ static int wtmp_islogin(struct logininfo *li, struct utmp *ut) { if (strncmp(li->username, ut->ut_name, MIN_SIZEOF(li->username, ut->ut_name)) == 0) { # ifdef HAVE_TYPE_IN_UTMP if (ut->ut_type & USER_PROCESS) return (1); # else return (1); # endif } return (0); } int wtmp_get_entry(struct logininfo *li) { struct stat st; struct utmp ut; int fd, found = 0; /* Clear the time entries in our logininfo */ li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { logit("%s: problem opening %s: %s", __func__, WTMP_FILE, strerror(errno)); return (0); } if (fstat(fd, &st) != 0) { logit("%s: couldn't stat %s: %s", __func__, WTMP_FILE, strerror(errno)); close(fd); return (0); } /* Seek to the start of the last struct utmp */ if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { /* Looks like we've got a fresh wtmp file */ close(fd); return (0); } while (!found) { if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { logit("%s: read of %s failed: %s", __func__, WTMP_FILE, strerror(errno)); close (fd); return (0); } if (wtmp_islogin(li, &ut) ) { found = 1; /* * We've already checked for a time in struct * utmp, in login_getlast() */ # ifdef HAVE_TIME_IN_UTMP li->tv_sec = ut.ut_time; # else # if HAVE_TV_IN_UTMP li->tv_sec = ut.ut_tv.tv_sec; # endif # endif line_fullname(li->line, ut.ut_line, MIN_SIZEOF(li->line, ut.ut_line)); # ifdef HAVE_HOST_IN_UTMP strlcpy(li->hostname, ut.ut_host, MIN_SIZEOF(li->hostname, ut.ut_host)); # endif continue; } /* Seek back 2 x struct utmp */ if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { /* We've found the start of the file, so quit */ close(fd); return (0); } } /* We found an entry. Tidy up and return */ close(fd); return (1); } # endif /* USE_WTMP */ /** ** Low-level wtmpx functions **/ #ifdef USE_WTMPX /* * Write a wtmpx entry direct to the end of the file * This is a slight modification of code in OpenBSD's logwtmp.c */ static int wtmpx_write(struct logininfo *li, struct utmpx *utx) { #ifndef HAVE_UPDWTMPX struct stat buf; int fd, ret = 1; if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { logit("%s: problem opening %s: %s", __func__, WTMPX_FILE, strerror(errno)); return (0); } if (fstat(fd, &buf) == 0) if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { ftruncate(fd, buf.st_size); logit("%s: problem writing %s: %s", __func__, WTMPX_FILE, strerror(errno)); ret = 0; } close(fd); return (ret); #else updwtmpx(WTMPX_FILE, utx); return (1); #endif } static int wtmpx_perform_login(struct logininfo *li) { struct utmpx utx; construct_utmpx(li, &utx); return (wtmpx_write(li, &utx)); } static int wtmpx_perform_logout(struct logininfo *li) { struct utmpx utx; construct_utmpx(li, &utx); return (wtmpx_write(li, &utx)); } int wtmpx_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return (wtmpx_perform_login(li)); case LTYPE_LOGOUT: return (wtmpx_perform_logout(li)); default: logit("%s: invalid type field", __func__); return (0); } } /* Please see the notes above wtmp_islogin() for information about the next two functions */ /* Return true if this wtmpx entry indicates a login */ static int wtmpx_islogin(struct logininfo *li, struct utmpx *utx) { if (strncmp(li->username, utx->ut_user, MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) { # ifdef HAVE_TYPE_IN_UTMPX if (utx->ut_type == USER_PROCESS) return (1); # else return (1); # endif } return (0); } int wtmpx_get_entry(struct logininfo *li) { struct stat st; struct utmpx utx; int fd, found=0; /* Clear the time entries */ li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { logit("%s: problem opening %s: %s", __func__, WTMPX_FILE, strerror(errno)); return (0); } if (fstat(fd, &st) != 0) { logit("%s: couldn't stat %s: %s", __func__, WTMPX_FILE, strerror(errno)); close(fd); return (0); } /* Seek to the start of the last struct utmpx */ if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { /* probably a newly rotated wtmpx file */ close(fd); return (0); } while (!found) { if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { logit("%s: read of %s failed: %s", __func__, WTMPX_FILE, strerror(errno)); close (fd); return (0); } /* * Logouts are recorded as a blank username on a particular * line. So, we just need to find the username in struct utmpx */ if (wtmpx_islogin(li, &utx)) { found = 1; # if defined(HAVE_TV_IN_UTMPX) li->tv_sec = utx.ut_tv.tv_sec; # elif defined(HAVE_TIME_IN_UTMPX) li->tv_sec = utx.ut_time; # endif line_fullname(li->line, utx.ut_line, sizeof(li->line)); # if defined(HAVE_HOST_IN_UTMPX) strlcpy(li->hostname, utx.ut_host, MIN_SIZEOF(li->hostname, utx.ut_host)); # endif continue; } if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { close(fd); return (0); } } close(fd); return (1); } #endif /* USE_WTMPX */ /** ** Low-level libutil login() functions **/ #ifdef USE_LOGIN static int syslogin_perform_login(struct logininfo *li) { struct utmp *ut; ut = xmalloc(sizeof(*ut)); construct_utmp(li, ut); login(ut); free(ut); return (1); } static int syslogin_perform_logout(struct logininfo *li) { # ifdef HAVE_LOGOUT char line[UT_LINESIZE]; (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) logit("%s: logout() returned an error", __func__); # ifdef HAVE_LOGWTMP else logwtmp(line, "", ""); # endif /* FIXME: (ATL - if the need arises) What to do if we have * login, but no logout? what if logout but no logwtmp? All * routines are in libutil so they should all be there, * but... */ # endif return (1); } int syslogin_write_entry(struct logininfo *li) { switch (li->type) { case LTYPE_LOGIN: return (syslogin_perform_login(li)); case LTYPE_LOGOUT: return (syslogin_perform_logout(li)); default: logit("%s: Invalid type field", __func__); return (0); } } #endif /* USE_LOGIN */ /* end of file log-syslogin.c */ /** ** Low-level lastlog functions **/ #ifdef USE_LASTLOG #if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME) /* open the file (using filemode) and seek to the login entry */ static int lastlog_openseek(struct logininfo *li, int *fd, int filemode) { off_t offset; char lastlog_file[1024]; struct stat st; if (stat(LASTLOG_FILE, &st) != 0) { logit("%s: Couldn't stat %s: %s", __func__, LASTLOG_FILE, strerror(errno)); return (0); } if (S_ISDIR(st.st_mode)) { snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", LASTLOG_FILE, li->username); } else if (S_ISREG(st.st_mode)) { strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); } else { logit("%s: %.100s is not a file or directory!", __func__, LASTLOG_FILE); return (0); } *fd = open(lastlog_file, filemode, 0600); if (*fd < 0) { debug("%s: Couldn't open %s: %s", __func__, lastlog_file, strerror(errno)); return (0); } if (S_ISREG(st.st_mode)) { /* find this uid's offset in the lastlog file */ offset = (off_t) ((u_long)li->uid * sizeof(struct lastlog)); if (lseek(*fd, offset, SEEK_SET) != offset) { logit("%s: %s->lseek(): %s", __func__, lastlog_file, strerror(errno)); close(*fd); return (0); } } return (1); } #endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */ #ifdef LASTLOG_WRITE_PUTUTXLINE int lastlog_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return 1; /* lastlog written by pututxline */ default: logit("lastlog_write_entry: Invalid type field"); return 0; } } #else /* LASTLOG_WRITE_PUTUTXLINE */ int lastlog_write_entry(struct logininfo *li) { struct lastlog last; int fd; switch(li->type) { case LTYPE_LOGIN: /* create our struct lastlog */ memset(&last, '\0', sizeof(last)); line_stripname(last.ll_line, li->line, sizeof(last.ll_line)); strlcpy(last.ll_host, li->hostname, MIN_SIZEOF(last.ll_host, li->hostname)); last.ll_time = li->tv_sec; if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) return (0); /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); logit("%s: Error writing to %s: %s", __func__, LASTLOG_FILE, strerror(errno)); return (0); } close(fd); return (1); default: logit("%s: Invalid type field", __func__); return (0); } } #endif /* LASTLOG_WRITE_PUTUTXLINE */ #ifdef HAVE_GETLASTLOGXBYNAME int lastlog_get_entry(struct logininfo *li) { struct lastlogx l, *ll; if ((ll = getlastlogxbyname(li->username, &l)) == NULL) { memset(&l, '\0', sizeof(l)); ll = &l; } line_fullname(li->line, ll->ll_line, sizeof(li->line)); strlcpy(li->hostname, ll->ll_host, MIN_SIZEOF(li->hostname, ll->ll_host)); li->tv_sec = ll->ll_tv.tv_sec; li->tv_usec = ll->ll_tv.tv_usec; return (1); } #else /* HAVE_GETLASTLOGXBYNAME */ int lastlog_get_entry(struct logininfo *li) { struct lastlog last; int fd, ret; if (!lastlog_openseek(li, &fd, O_RDONLY)) return (0); ret = atomicio(read, fd, &last, sizeof(last)); close(fd); switch (ret) { case 0: memset(&last, '\0', sizeof(last)); /* FALLTHRU */ case sizeof(last): line_fullname(li->line, last.ll_line, sizeof(li->line)); strlcpy(li->hostname, last.ll_host, MIN_SIZEOF(li->hostname, last.ll_host)); li->tv_sec = last.ll_time; return (1); case -1: error("%s: Error reading from %s: %s", __func__, LASTLOG_FILE, strerror(errno)); return (0); default: error("%s: Error reading from %s: Expecting %d, got %d", __func__, LASTLOG_FILE, (int)sizeof(last), ret); return (0); } /* NOTREACHED */ return (0); } #endif /* HAVE_GETLASTLOGXBYNAME */ #endif /* USE_LASTLOG */ #if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \ defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER) int utmpx_get_entry(struct logininfo *li) { struct utmpx *utx; if (setutxdb(UTXDB_LASTLOGIN, NULL) != 0) return (0); utx = getutxuser(li->username); if (utx == NULL) { endutxent(); return (0); } line_fullname(li->line, utx->ut_line, MIN_SIZEOF(li->line, utx->ut_line)); strlcpy(li->hostname, utx->ut_host, MIN_SIZEOF(li->hostname, utx->ut_host)); li->tv_sec = utx->ut_tv.tv_sec; li->tv_usec = utx->ut_tv.tv_usec; endutxent(); return (1); } #endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */ #ifdef USE_BTMP /* * Logs failed login attempts in _PATH_BTMP if that exists. * The most common login failure is to give password instead of username. * So the _PATH_BTMP file checked for the correct permission, so that * only root can read it. */ void record_failed_login(const char *username, const char *hostname, const char *ttyn) { int fd; struct utmp ut; struct sockaddr_storage from; socklen_t fromlen = sizeof(from); struct sockaddr_in *a4; struct sockaddr_in6 *a6; time_t t; struct stat fst; if (geteuid() != 0) return; if ((fd = open(_PATH_BTMP, O_WRONLY | O_APPEND)) < 0) { debug("Unable to open the btmp file %s: %s", _PATH_BTMP, strerror(errno)); return; } if (fstat(fd, &fst) < 0) { logit("%s: fstat of %s failed: %s", __func__, _PATH_BTMP, strerror(errno)); goto out; } if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){ logit("Excess permission or bad ownership on file %s", _PATH_BTMP); goto out; } memset(&ut, 0, sizeof(ut)); /* strncpy because we don't necessarily want nul termination */ strncpy(ut.ut_user, username, sizeof(ut.ut_user)); strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); time(&t); ut.ut_time = t; /* ut_time is not always a time_t */ ut.ut_type = LOGIN_PROCESS; ut.ut_pid = getpid(); /* strncpy because we don't necessarily want nul termination */ strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); if (packet_connection_is_on_socket() && getpeername(packet_get_connection_in(), (struct sockaddr *)&from, &fromlen) == 0) { ipv64_normalise_mapped(&from, &fromlen); if (from.ss_family == AF_INET) { a4 = (struct sockaddr_in *)&from; memcpy(&ut.ut_addr, &(a4->sin_addr), MIN_SIZEOF(ut.ut_addr, a4->sin_addr)); } #ifdef HAVE_ADDR_V6_IN_UTMP if (from.ss_family == AF_INET6) { a6 = (struct sockaddr_in6 *)&from; memcpy(&ut.ut_addr_v6, &(a6->sin6_addr), MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr)); } #endif } if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) error("Failed to write to %s: %s", _PATH_BTMP, strerror(errno)); out: close(fd); } #endif /* USE_BTMP */ openssh-7.2p2/loginrec.h010064400017500001750000000111501267006270000134230ustar00djmdjm#ifndef _HAVE_LOGINREC_H_ #define _HAVE_LOGINREC_H_ /* * Copyright (c) 2000 Andre Lucas. 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. */ /** ** loginrec.h: platform-independent login recording and lastlog retrieval **/ #include "includes.h" /** ** you should use the login_* calls to work around platform dependencies **/ /* * login_netinfo structure */ union login_netinfo { struct sockaddr sa; struct sockaddr_in sa_in; struct sockaddr_storage sa_storage; }; /* * * logininfo structure * */ /* types - different to utmp.h 'type' macros */ /* (though set to the same value as linux, openbsd and others...) */ #define LTYPE_LOGIN 7 #define LTYPE_LOGOUT 8 /* string lengths - set very long */ #define LINFO_PROGSIZE 64 #define LINFO_LINESIZE 64 #define LINFO_NAMESIZE 512 #define LINFO_HOSTSIZE 256 struct logininfo { char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ int progname_null; short int type; /* type of login (LTYPE_*) */ pid_t pid; /* PID of login process */ uid_t uid; /* UID of this user */ char line[LINFO_LINESIZE]; /* tty/pty name */ char username[LINFO_NAMESIZE]; /* login username */ char hostname[LINFO_HOSTSIZE]; /* remote hostname */ /* 'exit_status' structure components */ int exit; /* process exit status */ int termination; /* process termination status */ /* struct timeval (sys/time.h) isn't always available, if it isn't we'll * use time_t's value as tv_sec and set tv_usec to 0 */ unsigned int tv_sec; unsigned int tv_usec; union login_netinfo hostaddr; /* caller's host address(es) */ }; /* struct logininfo */ /* * login recording functions */ /** 'public' functions */ /* construct a new login entry */ struct logininfo *login_alloc_entry(pid_t pid, const char *username, const char *hostname, const char *line); /* free a structure */ void login_free_entry(struct logininfo *li); /* fill out a pre-allocated structure with useful information */ int login_init_entry(struct logininfo *li, pid_t pid, const char *username, const char *hostname, const char *line); /* place the current time in a logininfo struct */ void login_set_current_time(struct logininfo *li); /* record the entry */ int login_login (struct logininfo *li); int login_logout(struct logininfo *li); #ifdef LOGIN_NEEDS_UTMPX int login_utmp_only(struct logininfo *li); #endif /** End of public functions */ /* record the entry */ int login_write (struct logininfo *li); int login_log_entry(struct logininfo *li); /* set the network address based on network address type */ void login_set_addr(struct logininfo *li, const struct sockaddr *sa, const unsigned int sa_size); /* * lastlog retrieval functions */ /* lastlog *entry* functions fill out a logininfo */ struct logininfo *login_get_lastlog(struct logininfo *li, const uid_t uid); /* lastlog *time* functions return time_t equivalent (uint) */ unsigned int login_get_lastlog_time(const uid_t uid); /* produce various forms of the line filename */ char *line_fullname(char *dst, const char *src, u_int dstsize); char *line_stripname(char *dst, const char *src, int dstsize); char *line_abbrevname(char *dst, const char *src, int dstsize); void record_failed_login(const char *, const char *, const char *); #endif /* _HAVE_LOGINREC_H_ */ openssh-7.2p2/logintest.c010064400017500001750000000211241267006270000136260ustar00djmdjm/* * Copyright (c) 2000 Andre Lucas. 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. */ /** ** logintest.c: simple test driver for platform-independent login recording ** and lastlog retrieval **/ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_TIME_H #include #endif #include "loginrec.h" extern char *__progname; #define PAUSE_BEFORE_LOGOUT 3 int nologtest = 0; int compile_opts_only = 0; int be_verbose = 0; /* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */ void dump_logininfo(struct logininfo *li, char *descname) { /* yes I know how nasty this is */ printf("struct logininfo %s = {\n\t" "progname\t'%s'\n\ttype\t\t%d\n\t" "pid\t\t%d\n\tuid\t\t%d\n\t" "line\t\t'%s'\n\tusername\t'%s'\n\t" "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t" "tv_sec\t%d\n\ttv_usec\t%d\n\t" "struct login_netinfo hostaddr {\n\t\t" "struct sockaddr sa {\n" "\t\t\tfamily\t%d\n\t\t}\n" "\t}\n" "}\n", descname, li->progname, li->type, li->pid, li->uid, li->line, li->username, li->hostname, li->exit, li->termination, li->tv_sec, li->tv_usec, li->hostaddr.sa.sa_family); } int testAPI() { struct logininfo *li1; struct passwd *pw; struct hostent *he; struct sockaddr_in sa_in4; char cmdstring[256], stripline[8]; char username[32]; #ifdef HAVE_TIME_H time_t t0, t1, t2, logintime, logouttime; char s_t0[64],s_t1[64],s_t2[64]; char s_logintime[64], s_logouttime[64]; /* ctime() strings */ #endif printf("**\n** Testing the API...\n**\n"); pw = getpwuid(getuid()); strlcpy(username, pw->pw_name, sizeof(username)); /* gethostname(hostname, sizeof(hostname)); */ printf("login_alloc_entry test (no host info):\n"); /* FIXME fake tty more effectively - this could upset some platforms */ li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0)); strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname)); if (be_verbose) dump_logininfo(li1, "li1"); printf("Setting host address info for 'localhost' (may call out):\n"); if (! (he = gethostbyname("localhost"))) { printf("Couldn't set hostname(lookup failed)\n"); } else { /* NOTE: this is messy, but typically a program wouldn't have to set * any of this, a sockaddr_in* would be already prepared */ memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]), sizeof(struct in_addr)); login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4)); strlcpy(li1->hostname, "localhost", sizeof(li1->hostname)); } if (be_verbose) dump_logininfo(li1, "li1"); if ((int)geteuid() != 0) { printf("NOT RUNNING LOGIN TESTS - you are not root!\n"); return 1; } if (nologtest) return 1; line_stripname(stripline, li1->line, sizeof(stripline)); printf("Performing an invalid login attempt (no type field)\n--\n"); login_write(li1); printf("--\n(Should have written errors to stderr)\n"); #ifdef HAVE_TIME_H (void)time(&t0); strlcpy(s_t0, ctime(&t0), sizeof(s_t0)); t1 = login_get_lastlog_time(getuid()); strlcpy(s_t1, ctime(&t1), sizeof(s_t1)); printf("Before logging in:\n\tcurrent time is %d - %s\t" "lastlog time is %d - %s\n", (int)t0, s_t0, (int)t1, s_t1); #endif printf("Performing a login on line %s ", stripline); #ifdef HAVE_TIME_H (void)time(&logintime); strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime)); printf("at %d - %s", (int)logintime, s_logintime); #endif printf("--\n"); login_login(li1); snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '", stripline); system(cmdstring); printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT); sleep(PAUSE_BEFORE_LOGOUT); printf("Performing a logout "); #ifdef HAVE_TIME_H (void)time(&logouttime); strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime)); printf("at %d - %s", (int)logouttime, s_logouttime); #endif printf("\nThe root login shown above should be gone.\n" "If the root login hasn't gone, but another user on the same\n" "pty has, this is OK - we're hacking it here, and there\n" "shouldn't be two users on one pty in reality...\n" "-- ('who' output follows)\n"); login_logout(li1); system(cmdstring); printf("-- ('who' output ends)\n"); #ifdef HAVE_TIME_H t2 = login_get_lastlog_time(getuid()); strlcpy(s_t2, ctime(&t2), sizeof(s_t2)); printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2); if (t1 == t2) printf("The lastlog times before and after logging in are the " "same.\nThis indicates that lastlog is ** NOT WORKING " "CORRECTLY **\n"); else if (t0 != t2) /* We can be off by a second or so, even when recording works fine. * I'm not 100% sure why, but it's true. */ printf("** The login time and the lastlog time differ.\n" "** This indicates that lastlog is either recording the " "wrong time,\n** or retrieving the wrong entry.\n" "If it's off by less than %d second(s) " "run the test again.\n", PAUSE_BEFORE_LOGOUT); else printf("lastlog agrees with the login time. This is a good thing.\n"); #endif printf("--\nThe output of 'last' shown next should have " "an entry for root \n on %s for the time shown above:\n--\n", stripline); snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3", stripline); system(cmdstring); printf("--\nEnd of login test.\n"); login_free_entry(li1); return 1; } /* testAPI() */ void testLineName(char *line) { /* have to null-terminate - these functions are designed for * structures with fixed-length char arrays, and don't null-term.*/ char full[17], strip[9], abbrev[5]; memset(full, '\0', sizeof(full)); memset(strip, '\0', sizeof(strip)); memset(abbrev, '\0', sizeof(abbrev)); line_fullname(full, line, sizeof(full)-1); line_stripname(strip, full, sizeof(strip)-1); line_abbrevname(abbrev, full, sizeof(abbrev)-1); printf("%s: %s, %s, %s\n", line, full, strip, abbrev); } /* testLineName() */ int testOutput() { printf("**\n** Testing linename functions\n**\n"); testLineName("/dev/pts/1"); testLineName("pts/1"); testLineName("pts/999"); testLineName("/dev/ttyp00"); testLineName("ttyp00"); return 1; } /* testOutput() */ /* show which options got compiled in */ void showOptions(void) { printf("**\n** Compile-time options\n**\n"); printf("login recording methods selected:\n"); #ifdef USE_LOGIN printf("\tUSE_LOGIN\n"); #endif #ifdef USE_UTMP printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); #endif #ifdef USE_UTMPX printf("\tUSE_UTMPX\n"); #endif #ifdef USE_WTMP printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); #endif #ifdef USE_WTMPX printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE); #endif #ifdef USE_LASTLOG printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE); #endif printf("\n"); } /* showOptions() */ int main(int argc, char *argv[]) { printf("Platform-independent login recording test driver\n"); __progname = ssh_get_progname(argv[0]); if (argc == 2) { if (strncmp(argv[1], "-i", 3) == 0) compile_opts_only = 1; else if (strncmp(argv[1], "-v", 3) == 0) be_verbose=1; } if (!compile_opts_only) { if (be_verbose && !testOutput()) return 1; if (!testAPI()) return 1; } showOptions(); return 0; } /* main() */ openssh-7.2p2/mac.c010064400017500001750000000160501267006270000123600ustar00djmdjm/* $OpenBSD: mac.c,v 1.32 2015/01/15 18:32:54 naddy 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 #include #include #include "digest.h" #include "hmac.h" #include "umac.h" #include "mac.h" #include "misc.h" #include "ssherr.h" #include "sshbuf.h" #include "openbsd-compat/openssl-compat.h" #define SSH_DIGEST 1 /* SSH_DIGEST_XXX */ #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ #define SSH_UMAC128 3 struct macalg { char *name; int type; int alg; int truncatebits; /* truncate digest if != 0 */ int key_len; /* just for UMAC */ int len; /* just for UMAC */ int etm; /* Encrypt-then-MAC */ }; static const struct macalg macs[] = { /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, #ifdef HAVE_EVP_SHA256 { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, #endif { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, /* Encrypt-then-MAC variants */ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 }, #ifdef HAVE_EVP_SHA256 { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, #endif { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 }, { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 }, { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 }, { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 }, { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 }, { NULL, 0, 0, 0, 0, 0, 0 } }; /* Returns a list of supported MACs separated by the specified char. */ char * mac_alg_list(char sep) { char *ret = NULL, *tmp; size_t nlen, rlen = 0; const struct macalg *m; for (m = macs; m->name != NULL; m++) { if (ret != NULL) ret[rlen++] = sep; nlen = strlen(m->name); if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { free(ret); return NULL; } ret = tmp; memcpy(ret + rlen, m->name, nlen + 1); rlen += nlen; } return ret; } static int mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg) { mac->type = macalg->type; if (mac->type == SSH_DIGEST) { if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL) return SSH_ERR_ALLOC_FAIL; mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); } else { mac->mac_len = macalg->len / 8; mac->key_len = macalg->key_len / 8; mac->umac_ctx = NULL; } if (macalg->truncatebits != 0) mac->mac_len = macalg->truncatebits / 8; mac->etm = macalg->etm; return 0; } int mac_setup(struct sshmac *mac, char *name) { const struct macalg *m; for (m = macs; m->name != NULL; m++) { if (strcmp(name, m->name) != 0) continue; if (mac != NULL) return mac_setup_by_alg(mac, m); return 0; } return SSH_ERR_INVALID_ARGUMENT; } int mac_init(struct sshmac *mac) { if (mac->key == NULL) return SSH_ERR_INVALID_ARGUMENT; switch (mac->type) { case SSH_DIGEST: if (mac->hmac_ctx == NULL || ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) return SSH_ERR_INVALID_ARGUMENT; return 0; case SSH_UMAC: if ((mac->umac_ctx = umac_new(mac->key)) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; case SSH_UMAC128: if ((mac->umac_ctx = umac128_new(mac->key)) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; default: return SSH_ERR_INVALID_ARGUMENT; } } int mac_compute(struct sshmac *mac, u_int32_t seqno, const u_char *data, int datalen, u_char *digest, size_t dlen) { static union { u_char m[SSH_DIGEST_MAX_LENGTH]; u_int64_t for_align; } u; u_char b[4]; u_char nonce[8]; if (mac->mac_len > sizeof(u)) return SSH_ERR_INTERNAL_ERROR; switch (mac->type) { case SSH_DIGEST: put_u32(b, seqno); /* reset HMAC context */ if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 || ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) return SSH_ERR_LIBCRYPTO_ERROR; break; case SSH_UMAC: POKE_U64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, u.m, nonce); break; case SSH_UMAC128: put_u64(nonce, seqno); umac128_update(mac->umac_ctx, data, datalen); umac128_final(mac->umac_ctx, u.m, nonce); break; default: return SSH_ERR_INVALID_ARGUMENT; } if (digest != NULL) { if (dlen > mac->mac_len) dlen = mac->mac_len; memcpy(digest, u.m, dlen); } return 0; } void mac_clear(struct sshmac *mac) { if (mac->type == SSH_UMAC) { if (mac->umac_ctx != NULL) umac_delete(mac->umac_ctx); } else if (mac->type == SSH_UMAC128) { if (mac->umac_ctx != NULL) umac128_delete(mac->umac_ctx); } else if (mac->hmac_ctx != NULL) ssh_hmac_free(mac->hmac_ctx); mac->hmac_ctx = NULL; mac->umac_ctx = NULL; } /* XXX copied from ciphers_valid */ #define MAC_SEP "," int mac_valid(const char *names) { char *maclist, *cp, *p; if (names == NULL || strcmp(names, "") == 0) return 0; if ((maclist = cp = strdup(names)) == NULL) return 0; for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; (p = strsep(&cp, MAC_SEP))) { if (mac_setup(NULL, p) < 0) { free(maclist); return 0; } } free(maclist); return 1; } openssh-7.2p2/mac.h010064400017500001750000000035671267006270000123760ustar00djmdjm/* $OpenBSD: mac.h,v 1.9 2015/01/13 19:31:40 markus 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. */ #ifndef SSHMAC_H #define SSHMAC_H #include struct sshmac { char *name; int enabled; u_int mac_len; u_char *key; u_int key_len; int type; int etm; /* Encrypt-then-MAC */ struct ssh_hmac_ctx *hmac_ctx; struct umac_ctx *umac_ctx; }; int mac_valid(const char *); char *mac_alg_list(char); int mac_setup(struct sshmac *, char *); int mac_init(struct sshmac *); int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, u_char *, size_t); void mac_clear(struct sshmac *); #endif /* SSHMAC_H */ openssh-7.2p2/match.c010064400017500001750000000163341267006270000127210ustar00djmdjm/* $OpenBSD: match.c,v 1.30 2015/05/04 06:10:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Simple pattern matching, with '*' and '?' as wildcards. * * 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 #include #include #include #include "xmalloc.h" #include "match.h" /* * Returns true if the given string matches the pattern (which may contain ? * and * as wildcards), and zero if it does not match. */ int match_pattern(const char *s, const char *pattern) { for (;;) { /* If at end of pattern, accept if also at end of string. */ if (!*pattern) return !*s; if (*pattern == '*') { /* Skip the asterisk. */ pattern++; /* If at end of pattern, accept immediately. */ if (!*pattern) return 1; /* If next character in pattern is known, optimize. */ if (*pattern != '?' && *pattern != '*') { /* * Look instances of the next character in * pattern, and try to match starting from * those. */ for (; *s; s++) if (*s == *pattern && match_pattern(s + 1, pattern + 1)) return 1; /* Failed. */ return 0; } /* * Move ahead one character at a time and try to * match at each position. */ for (; *s; s++) if (match_pattern(s, pattern)) return 1; /* Failed. */ return 0; } /* * There must be at least one more character in the string. * If we are at the end, fail. */ if (!*s) return 0; /* Check if the next character of the string is acceptable. */ if (*pattern != '?' && *pattern != *s) return 0; /* Move to the next character, both in string and in pattern. */ s++; pattern++; } /* NOTREACHED */ } /* * Tries to match the string against the * comma-separated sequence of subpatterns (each possibly preceded by ! to * indicate negation). Returns -1 if negation matches, 1 if there is * a positive match, 0 if there is no match at all. */ int match_pattern_list(const char *string, const char *pattern, int dolower) { char sub[1024]; int negated; int got_positive; u_int i, subi, len = strlen(pattern); got_positive = 0; for (i = 0; i < len;) { /* Check if the subpattern is negated. */ if (pattern[i] == '!') { negated = 1; i++; } else negated = 0; /* * Extract the subpattern up to a comma or end. Convert the * subpattern to lowercase. */ for (subi = 0; i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; subi++, i++) sub[subi] = dolower && isupper((u_char)pattern[i]) ? tolower((u_char)pattern[i]) : pattern[i]; /* If subpattern too long, return failure (no match). */ if (subi >= sizeof(sub) - 1) return 0; /* If the subpattern was terminated by a comma, skip the comma. */ if (i < len && pattern[i] == ',') i++; /* Null-terminate the subpattern. */ sub[subi] = '\0'; /* Try to match the subpattern against the string. */ if (match_pattern(string, sub)) { if (negated) return -1; /* Negative */ else got_positive = 1; /* Positive */ } } /* * Return success if got a positive match. If there was a negative * match, we have already returned -1 and never get here. */ return got_positive; } /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to * indicate negation). Returns -1 if negation matches, 1 if there is * a positive match, 0 if there is no match at all. */ int match_hostname(const char *host, const char *pattern) { return match_pattern_list(host, pattern, 1); } /* * returns 0 if we get a negative match for the hostname or the ip * or if we get no match at all. returns -1 on error, or 1 on * successful match. */ int match_host_and_ip(const char *host, const char *ipaddr, const char *patterns) { int mhost, mip; /* error in ipaddr match */ if ((mip = addr_match_list(ipaddr, patterns)) == -2) return -1; else if (mip == -1) /* negative ip address match */ return 0; /* negative hostname match */ if ((mhost = match_hostname(host, patterns)) == -1) return 0; /* no match at all */ if (mhost == 0 && mip == 0) return 0; return 1; } /* * match user, user@host_or_ip, user@host_or_ip_list against pattern */ int match_user(const char *user, const char *host, const char *ipaddr, const char *pattern) { char *p, *pat; int ret; if ((p = strchr(pattern,'@')) == NULL) return match_pattern(user, pattern); pat = xstrdup(pattern); p = strchr(pat, '@'); *p++ = '\0'; if ((ret = match_pattern(user, pat)) == 1) ret = match_host_and_ip(host, ipaddr, p); free(pat); return ret; } /* * Returns first item from client-list that is also supported by server-list, * caller must free the returned string. */ #define MAX_PROP 40 #define SEP "," char * match_list(const char *client, const char *server, u_int *next) { char *sproposals[MAX_PROP]; char *c, *s, *p, *ret, *cp, *sp; int i, j, nproposals; c = cp = xstrdup(client); s = sp = xstrdup(server); for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0'; (p = strsep(&sp, SEP)), i++) { if (i < MAX_PROP) sproposals[i] = p; else break; } nproposals = i; for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0'; (p = strsep(&cp, SEP)), i++) { for (j = 0; j < nproposals; j++) { if (strcmp(p, sproposals[j]) == 0) { ret = xstrdup(p); if (next != NULL) *next = (cp == NULL) ? strlen(c) : (u_int)(cp - c); free(c); free(s); return ret; } } } if (next != NULL) *next = strlen(c); free(c); free(s); return NULL; } openssh-7.2p2/match.h010064400017500001750000000020611267006270000127160ustar00djmdjm/* $OpenBSD: match.h,v 1.16 2015/05/04 06:10:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 MATCH_H #define MATCH_H int match_pattern(const char *, const char *); int match_pattern_list(const char *, const char *, int); int match_hostname(const char *, const char *); int match_host_and_ip(const char *, const char *, const char *); int match_user(const char *, const char *, const char *, const char *); char *match_list(const char *, const char *, u_int *); /* addrmatch.c */ int addr_match_list(const char *, const char *); int addr_match_cidr_list(const char *, const char *); #endif openssh-7.2p2/md-sha256.c010064400017500001750000000043501267006270000132260ustar00djmdjm/* $OpenBSD: md-sha256.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */ /* * Copyright (c) 2005 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* EVP wrapper for SHA256 */ #include "includes.h" #include #include #if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) #include #include #ifdef HAVE_SHA256_UPDATE # ifdef HAVE_SHA2_H # include # elif defined(HAVE_CRYPTO_SHA2_H) # include # endif #endif const EVP_MD *evp_ssh_sha256(void); static int ssh_sha256_init(EVP_MD_CTX *ctxt) { SHA256_Init(ctxt->md_data); return (1); } static int ssh_sha256_update(EVP_MD_CTX *ctxt, const void *data, unsigned long len) { SHA256_Update(ctxt->md_data, data, len); return (1); } static int ssh_sha256_final(EVP_MD_CTX *ctxt, unsigned char *digest) { SHA256_Final(digest, ctxt->md_data); return (1); } static int ssh_sha256_cleanup(EVP_MD_CTX *ctxt) { memset(ctxt->md_data, 0, sizeof(SHA256_CTX)); return (1); } const EVP_MD * evp_ssh_sha256(void) { static EVP_MD ssh_sha256; memset(&ssh_sha256, 0, sizeof(ssh_sha256)); ssh_sha256.type = NID_undef; ssh_sha256.md_size = SHA256_DIGEST_LENGTH; ssh_sha256.init = ssh_sha256_init; ssh_sha256.update = ssh_sha256_update; ssh_sha256.final = ssh_sha256_final; ssh_sha256.cleanup = ssh_sha256_cleanup; ssh_sha256.block_size = SHA256_BLOCK_LENGTH; ssh_sha256.ctx_size = sizeof(SHA256_CTX); return (&ssh_sha256); } #endif /* !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) */ openssh-7.2p2/md5crypt.c010064400017500001750000000100211267006270000133570ustar00djmdjm/* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * 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 * ---------------------------------------------------------------------------- */ #include "includes.h" #if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) #include #include #include /* 0 ... 63 => ascii - 64 */ static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static char *magic = "$1$"; static char * to64(unsigned long v, int n) { static char buf[5]; char *s = buf; if (n > 4) return (NULL); memset(buf, '\0', sizeof(buf)); while (--n >= 0) { *s++ = itoa64[v&0x3f]; v >>= 6; } return (buf); } int is_md5_salt(const char *salt) { return (strncmp(salt, magic, strlen(magic)) == 0); } char * md5_crypt(const char *pw, const char *salt) { static char passwd[120], salt_copy[9], *p; static const char *sp, *ep; unsigned char final[16]; int sl, pl, i, j; MD5_CTX ctx, ctx1; unsigned long l; /* Refine the Salt first */ sp = salt; /* If it starts with the magic string, then skip that */ if(strncmp(sp, magic, strlen(magic)) == 0) sp += strlen(magic); /* It stops at the first '$', max 8 chars */ for (ep = sp; *ep != '$'; ep++) { if (*ep == '\0' || ep >= (sp + 8)) return (NULL); } /* get the length of the true salt */ sl = ep - sp; /* Stash the salt */ memcpy(salt_copy, sp, sl); salt_copy[sl] = '\0'; MD5_Init(&ctx); /* The password first, since that is what is most unknown */ MD5_Update(&ctx, pw, strlen(pw)); /* Then our magic string */ MD5_Update(&ctx, magic, strlen(magic)); /* Then the raw salt */ MD5_Update(&ctx, sp, sl); /* Then just as many characters of the MD5(pw, salt, pw) */ MD5_Init(&ctx1); MD5_Update(&ctx1, pw, strlen(pw)); MD5_Update(&ctx1, sp, sl); MD5_Update(&ctx1, pw, strlen(pw)); MD5_Final(final, &ctx1); for(pl = strlen(pw); pl > 0; pl -= 16) MD5_Update(&ctx, final, pl > 16 ? 16 : pl); /* Don't leave anything around in vm they could use. */ memset(final, '\0', sizeof final); /* Then something really weird... */ for (j = 0, i = strlen(pw); i != 0; i >>= 1) if (i & 1) MD5_Update(&ctx, final + j, 1); else MD5_Update(&ctx, pw + j, 1); /* Now make the output string */ snprintf(passwd, sizeof(passwd), "%s%s$", magic, salt_copy); MD5_Final(final, &ctx); /* * and now, just to make sure things don't run too fast * On a 60 Mhz Pentium this takes 34 msec, so you would * need 30 seconds to build a 1000 entry dictionary... */ for(i = 0; i < 1000; i++) { MD5_Init(&ctx1); if (i & 1) MD5_Update(&ctx1, pw, strlen(pw)); else MD5_Update(&ctx1, final, 16); if (i % 3) MD5_Update(&ctx1, sp, sl); if (i % 7) MD5_Update(&ctx1, pw, strlen(pw)); if (i & 1) MD5_Update(&ctx1, final, 16); else MD5_Update(&ctx1, pw, strlen(pw)); MD5_Final(final, &ctx1); } p = passwd + strlen(passwd); l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; strlcat(passwd, to64(l, 4), sizeof(passwd)); l = final[11] ; strlcat(passwd, to64(l, 2), sizeof(passwd)); /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof(final)); memset(salt_copy, 0, sizeof(salt_copy)); memset(&ctx, 0, sizeof(ctx)); memset(&ctx1, 0, sizeof(ctx1)); (void)to64(0, 4); return (passwd); } #endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ openssh-7.2p2/md5crypt.h010064400017500001750000000014431267006270000133740ustar00djmdjm/* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * 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 * ---------------------------------------------------------------------------- */ /* $Id: md5crypt.h,v 1.4 2003/05/18 14:46:46 djm Exp $ */ #ifndef _MD5CRYPT_H #define _MD5CRYPT_H #include "config.h" #if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) int is_md5_salt(const char *); char *md5_crypt(const char *, const char *); #endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ #endif /* MD5CRYPT_H */ openssh-7.2p2/mdoc2man.awk010064400017500001750000000206401267006270000136600ustar00djmdjm#!/usr/bin/awk # # $Id: mdoc2man.awk,v 1.9 2009/10/24 00:52:42 dtucker Exp $ # # Version history: # v4+ Adapted for OpenSSH Portable (see cvs Id and history) # v3, I put the program under a proper license # Dan Nelson added .An, .Aq and fixed a typo # v2, fixed to work on GNU awk --posix and MacOS X # v1, first attempt, didn't work on MacOS X # # Copyright (c) 2003 Peter Stuge # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. BEGIN { optlist=0 oldoptlist=0 nospace=0 synopsis=0 reference=0 block=0 ext=0 extopt=0 literal=0 prenl=0 breakw=0 line="" } function wtail() { retval="" while(w0;i--) { add(refauthors[i]) if(i>1) add(", ") } if(nrefauthors>1) add(" and ") if(nrefauthors>0) add(refauthors[0] ", ") add("\\fI" reftitle "\\fP") if(length(refissue)) add(", " refissue) if(length(refreport)) { add(", " refreport) } if(length(refdate)) add(", " refdate) if(length(refopt)) add(", " refopt) add(".") reference=0 } else if(reference) { if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() } if(match(words[w],"^%T$")) { reftitle=wtail() sub("^\"","",reftitle) sub("\"$","",reftitle) } if(match(words[w],"^%N$")) { refissue=wtail() } if(match(words[w],"^%D$")) { refdate=wtail() } if(match(words[w],"^%O$")) { refopt=wtail() } if(match(words[w],"^%R$")) { refreport=wtail() } } else if(match(words[w],"^Nm$")) { if(synopsis) { add(".br") prenl++ } n=words[++w] if(!length(name)) name=n if(!length(n)) n=name add("\\fB" n "\\fP") if(!nospace&&match(words[w+1],"^[\\.,]")) nospace=1 } else if(match(words[w],"^Nd$")) { add("\\- " wtail()) } else if(match(words[w],"^Fl$")) { add("\\fB\\-" words[++w] "\\fP") if(!nospace&&match(words[w+1],"^[\\.,]")) nospace=1 } else if(match(words[w],"^Ar$")) { add("\\fI") if(w==nwords) add("file ...\\fP") else { add(words[++w] "\\fP") while(match(words[w+1],"^\\|$")) add(OFS words[++w] " \\fI" words[++w] "\\fP") } if(!nospace&&match(words[w+1],"^[\\.,]")) nospace=1 } else if(match(words[w],"^Cm$")) { add("\\fB" words[++w] "\\fP") while(w") if(option) add("]") if(ext&&!extopt&&!match(line," $")) add(OFS) if(!ext&&!extopt&&length(line)) { print line prenl=0 line="" } } openssh-7.2p2/misc.c010064400017500001750000000561211267006270000125560ustar00djmdjm/* $OpenBSD: misc.c,v 1.101 2016/01/20 09:22:39 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_PATHS_H # include #include #endif #ifdef SSH_TUN_OPENBSD #include #endif #include "xmalloc.h" #include "misc.h" #include "log.h" #include "ssh.h" /* remove newline at end of string */ char * chop(char *s) { char *t = s; while (*t) { if (*t == '\n' || *t == '\r') { *t = '\0'; return s; } t++; } return s; } /* set/unset filedescriptor to non-blocking */ int 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 (-1); } if (val & O_NONBLOCK) { debug3("fd %d is O_NONBLOCK", fd); return (0); } debug2("fd %d setting O_NONBLOCK", fd); val |= O_NONBLOCK; if (fcntl(fd, F_SETFL, val) == -1) { debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno)); return (-1); } return (0); } int unset_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 (-1); } if (!(val & O_NONBLOCK)) { debug3("fd %d is not O_NONBLOCK", fd); return (0); } debug("fd %d clearing O_NONBLOCK", fd); val &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, val) == -1) { debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", fd, strerror(errno)); return (-1); } return (0); } const char * ssh_gai_strerror(int gaierr) { if (gaierr == EAI_SYSTEM && errno != 0) return strerror(errno); return gai_strerror(gaierr); } /* disable nagle on socket */ void set_nodelay(int fd) { int opt; socklen_t optlen; optlen = sizeof opt; if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); return; } if (opt == 1) { debug2("fd %d is TCP_NODELAY", fd); return; } opt = 1; debug2("fd %d setting TCP_NODELAY", fd); if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); } /* Characters considered whitespace in strsep calls. */ #define WHITESPACE " \t\r\n" #define QUOTE "\"" /* return next token in configuration line */ char * strdelim(char **s) { char *old; int wspace = 0; if (*s == NULL) return NULL; old = *s; *s = strpbrk(*s, WHITESPACE QUOTE "="); if (*s == NULL) return (old); if (*s[0] == '\"') { memmove(*s, *s + 1, strlen(*s)); /* move nul too */ /* Find matching quote */ if ((*s = strpbrk(*s, QUOTE)) == NULL) { return (NULL); /* no matching quote */ } else { *s[0] = '\0'; *s += strspn(*s + 1, WHITESPACE) + 1; return (old); } } /* Allow only one '=' to be skipped */ if (*s[0] == '=') wspace = 1; *s[0] = '\0'; /* Skip any extra whitespace after first token */ *s += strspn(*s + 1, WHITESPACE) + 1; if (*s[0] == '=' && !wspace) *s += strspn(*s + 1, WHITESPACE) + 1; return (old); } struct passwd * pwcopy(struct passwd *pw) { struct passwd *copy = xcalloc(1, sizeof(*copy)); copy->pw_name = xstrdup(pw->pw_name); copy->pw_passwd = xstrdup(pw->pw_passwd); #ifdef HAVE_STRUCT_PASSWD_PW_GECOS copy->pw_gecos = xstrdup(pw->pw_gecos); #endif copy->pw_uid = pw->pw_uid; copy->pw_gid = pw->pw_gid; #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE copy->pw_expire = pw->pw_expire; #endif #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE copy->pw_change = pw->pw_change; #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS copy->pw_class = xstrdup(pw->pw_class); #endif copy->pw_dir = xstrdup(pw->pw_dir); copy->pw_shell = xstrdup(pw->pw_shell); return copy; } /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. * Return -1 if invalid. */ int a2port(const char *s) { long long port; const char *errstr; port = strtonum(s, 0, 65535, &errstr); if (errstr != NULL) return -1; return (int)port; } int a2tun(const char *s, int *remote) { const char *errstr = NULL; char *sp, *ep; int tun; if (remote != NULL) { *remote = SSH_TUNID_ANY; sp = xstrdup(s); if ((ep = strchr(sp, ':')) == NULL) { free(sp); return (a2tun(s, NULL)); } ep[0] = '\0'; ep++; *remote = a2tun(ep, NULL); tun = a2tun(sp, NULL); free(sp); return (*remote == SSH_TUNID_ERR ? *remote : tun); } if (strcasecmp(s, "any") == 0) return (SSH_TUNID_ANY); tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); if (errstr != NULL) return (SSH_TUNID_ERR); return (tun); } #define SECONDS 1 #define MINUTES (SECONDS * 60) #define HOURS (MINUTES * 60) #define DAYS (HOURS * 24) #define WEEKS (DAYS * 7) /* * Convert a time string into seconds; format is * a sequence of: * time[qualifier] * * Valid time qualifiers are: * seconds * s|S seconds * m|M minutes * h|H hours * d|D days * w|W weeks * * Examples: * 90m 90 minutes * 1h30m 90 minutes * 2d 2 days * 1w 1 week * * Return -1 if time string is invalid. */ long convtime(const char *s) { long total, secs; const char *p; char *endp; errno = 0; total = 0; p = s; if (p == NULL || *p == '\0') return -1; while (*p) { secs = strtol(p, &endp, 10); if (p == endp || (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || secs < 0) return -1; switch (*endp++) { case '\0': endp--; break; case 's': case 'S': break; case 'm': case 'M': secs *= MINUTES; break; case 'h': case 'H': secs *= HOURS; break; case 'd': case 'D': secs *= DAYS; break; case 'w': case 'W': secs *= WEEKS; break; default: return -1; } total += secs; if (total < 0) return -1; p = endp; } return total; } /* * Returns a standardized host+port identifier string. * Caller must free returned string. */ char * put_host_port(const char *host, u_short port) { char *hoststr; if (port == 0 || port == SSH_DEFAULT_PORT) return(xstrdup(host)); if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) fatal("put_host_port: asprintf: %s", strerror(errno)); debug3("put_host_port: %s", hoststr); return hoststr; } /* * Search for next delimiter between hostnames/addresses and ports. * Argument may be modified (for termination). * Returns *cp if parsing succeeds. * *cp is set to the start of the next delimiter, if one was found. * If this is the last field, *cp is set to NULL. */ char * hpdelim(char **cp) { char *s, *old; if (cp == NULL || *cp == NULL) return NULL; old = s = *cp; if (*s == '[') { if ((s = strchr(s, ']')) == NULL) return NULL; else s++; } else if ((s = strpbrk(s, ":/")) == NULL) s = *cp + strlen(*cp); /* skip to end (see first case below) */ switch (*s) { case '\0': *cp = NULL; /* no more fields*/ break; case ':': case '/': *s = '\0'; /* terminate */ *cp = s + 1; break; default: return NULL; } return old; } char * cleanhostname(char *host) { if (*host == '[' && host[strlen(host) - 1] == ']') { host[strlen(host) - 1] = '\0'; return (host + 1); } else return host; } char * colon(char *cp) { int flag = 0; if (*cp == ':') /* Leading colon is part of file name. */ return NULL; if (*cp == '[') flag = 1; for (; *cp; ++cp) { if (*cp == '@' && *(cp+1) == '[') flag = 1; if (*cp == ']' && *(cp+1) == ':' && flag) return (cp+1); if (*cp == ':' && !flag) return (cp); if (*cp == '/') return NULL; } return NULL; } /* function to assist building execv() arguments */ void addargs(arglist *args, char *fmt, ...) { va_list ap; char *cp; u_int nalloc; int r; va_start(ap, fmt); r = vasprintf(&cp, fmt, ap); va_end(ap); if (r == -1) fatal("addargs: argument too long"); nalloc = args->nalloc; if (args->list == NULL) { nalloc = 32; args->num = 0; } else if (args->num+2 >= nalloc) nalloc *= 2; args->list = xreallocarray(args->list, nalloc, sizeof(char *)); args->nalloc = nalloc; args->list[args->num++] = cp; args->list[args->num] = NULL; } void replacearg(arglist *args, u_int which, char *fmt, ...) { va_list ap; char *cp; int r; va_start(ap, fmt); r = vasprintf(&cp, fmt, ap); va_end(ap); if (r == -1) fatal("replacearg: argument too long"); if (which >= args->num) fatal("replacearg: tried to replace invalid arg %d >= %d", which, args->num); free(args->list[which]); args->list[which] = cp; } void freeargs(arglist *args) { u_int i; if (args->list != NULL) { for (i = 0; i < args->num; i++) free(args->list[i]); free(args->list); args->nalloc = args->num = 0; args->list = NULL; } } /* * Expands tildes in the file name. Returns data allocated by xmalloc. * Warning: this calls getpw*. */ char * tilde_expand_filename(const char *filename, uid_t uid) { const char *path, *sep; char user[128], *ret; struct passwd *pw; u_int len, slash; if (*filename != '~') return (xstrdup(filename)); filename++; path = strchr(filename, '/'); if (path != NULL && path > filename) { /* ~user/path */ slash = path - filename; if (slash > sizeof(user) - 1) fatal("tilde_expand_filename: ~username too long"); memcpy(user, filename, slash); user[slash] = '\0'; if ((pw = getpwnam(user)) == NULL) fatal("tilde_expand_filename: No such user %s", user); } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ fatal("tilde_expand_filename: No such uid %ld", (long)uid); /* Make sure directory has a trailing '/' */ len = strlen(pw->pw_dir); if (len == 0 || pw->pw_dir[len - 1] != '/') sep = "/"; else sep = ""; /* Skip leading '/' from specified path */ if (path != NULL) filename = path + 1; if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) fatal("tilde_expand_filename: Path too long"); return (ret); } /* * Expand a string with a set of %[char] escapes. A number of escapes may be * specified as (char *escape_chars, char *replacement) pairs. The list must * be terminated by a NULL escape_char. Returns replaced string in memory * allocated by xmalloc. */ char * percent_expand(const char *string, ...) { #define EXPAND_MAX_KEYS 16 u_int num_keys, i, j; struct { const char *key; const char *repl; } keys[EXPAND_MAX_KEYS]; char buf[4096]; va_list ap; /* Gather keys */ va_start(ap, string); for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { keys[num_keys].key = va_arg(ap, char *); if (keys[num_keys].key == NULL) break; keys[num_keys].repl = va_arg(ap, char *); if (keys[num_keys].repl == NULL) fatal("%s: NULL replacement", __func__); } if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) fatal("%s: too many keys", __func__); va_end(ap); /* Expand string */ *buf = '\0'; for (i = 0; *string != '\0'; string++) { if (*string != '%') { append: buf[i++] = *string; if (i >= sizeof(buf)) fatal("%s: string too long", __func__); buf[i] = '\0'; continue; } string++; /* %% case */ if (*string == '%') goto append; if (*string == '\0') fatal("%s: invalid format", __func__); for (j = 0; j < num_keys; j++) { if (strchr(keys[j].key, *string) != NULL) { i = strlcat(buf, keys[j].repl, sizeof(buf)); if (i >= sizeof(buf)) fatal("%s: string too long", __func__); break; } } if (j >= num_keys) fatal("%s: unknown key %%%c", __func__, *string); } return (xstrdup(buf)); #undef EXPAND_MAX_KEYS } /* * Read an entire line from a public key file into a static buffer, discarding * lines that exceed the buffer size. Returns 0 on success, -1 on failure. */ int read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, u_long *lineno) { while (fgets(buf, bufsz, f) != NULL) { if (buf[0] == '\0') continue; (*lineno)++; if (buf[strlen(buf) - 1] == '\n' || feof(f)) { return 0; } else { debug("%s: %s line %lu exceeds size limit", __func__, filename, *lineno); /* discard remainder of line */ while (fgetc(f) != '\n' && !feof(f)) ; /* nothing */ } } return -1; } int tun_open(int tun, int mode) { #if defined(CUSTOM_SYS_TUN_OPEN) return (sys_tun_open(tun, mode)); #elif defined(SSH_TUN_OPENBSD) struct ifreq ifr; char name[100]; int fd = -1, sock; const char *tunbase = "tun"; if (mode == SSH_TUNMODE_ETHERNET) tunbase = "tap"; /* Open the tunnel device */ if (tun <= SSH_TUNID_MAX) { snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); fd = open(name, O_RDWR); } else if (tun == SSH_TUNID_ANY) { for (tun = 100; tun >= 0; tun--) { snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); if ((fd = open(name, O_RDWR)) >= 0) break; } } else { debug("%s: invalid tunnel %u", __func__, tun); return -1; } if (fd < 0) { debug("%s: %s open: %s", __func__, name, strerror(errno)); return -1; } debug("%s: %s mode %d fd %d", __func__, name, mode, fd); /* Bring interface up if it is not already */ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) goto failed; if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { debug("%s: get interface %s flags: %s", __func__, ifr.ifr_name, strerror(errno)); goto failed; } if (!(ifr.ifr_flags & IFF_UP)) { ifr.ifr_flags |= IFF_UP; if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { debug("%s: activate interface %s: %s", __func__, ifr.ifr_name, strerror(errno)); goto failed; } } close(sock); return fd; failed: if (fd >= 0) close(fd); if (sock >= 0) close(sock); return -1; #else error("Tunnel interfaces are not supported on this platform"); return (-1); #endif } void sanitise_stdfd(void) { int nullfd, dupfd; if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { fprintf(stderr, "Couldn't open /dev/null: %s\n", strerror(errno)); exit(1); } while (++dupfd <= 2) { /* Only clobber closed fds */ if (fcntl(dupfd, F_GETFL, 0) >= 0) continue; if (dup2(nullfd, dupfd) == -1) { fprintf(stderr, "dup2: %s\n", strerror(errno)); exit(1); } } if (nullfd > 2) close(nullfd); } char * tohex(const void *vp, size_t l) { const u_char *p = (const u_char *)vp; char b[3], *r; size_t i, hl; if (l > 65536) return xstrdup("tohex: length > 65536"); hl = l * 2 + 1; r = xcalloc(1, hl); for (i = 0; i < l; i++) { snprintf(b, sizeof(b), "%02x", p[i]); strlcat(r, b, hl); } return (r); } u_int64_t get_u64(const void *vp) { const u_char *p = (const u_char *)vp; u_int64_t v; v = (u_int64_t)p[0] << 56; v |= (u_int64_t)p[1] << 48; v |= (u_int64_t)p[2] << 40; v |= (u_int64_t)p[3] << 32; v |= (u_int64_t)p[4] << 24; v |= (u_int64_t)p[5] << 16; v |= (u_int64_t)p[6] << 8; v |= (u_int64_t)p[7]; return (v); } u_int32_t get_u32(const void *vp) { const u_char *p = (const u_char *)vp; u_int32_t v; v = (u_int32_t)p[0] << 24; v |= (u_int32_t)p[1] << 16; v |= (u_int32_t)p[2] << 8; v |= (u_int32_t)p[3]; return (v); } u_int32_t get_u32_le(const void *vp) { const u_char *p = (const u_char *)vp; u_int32_t v; v = (u_int32_t)p[0]; v |= (u_int32_t)p[1] << 8; v |= (u_int32_t)p[2] << 16; v |= (u_int32_t)p[3] << 24; return (v); } u_int16_t get_u16(const void *vp) { const u_char *p = (const u_char *)vp; u_int16_t v; v = (u_int16_t)p[0] << 8; v |= (u_int16_t)p[1]; return (v); } void put_u64(void *vp, u_int64_t v) { u_char *p = (u_char *)vp; p[0] = (u_char)(v >> 56) & 0xff; p[1] = (u_char)(v >> 48) & 0xff; p[2] = (u_char)(v >> 40) & 0xff; p[3] = (u_char)(v >> 32) & 0xff; p[4] = (u_char)(v >> 24) & 0xff; p[5] = (u_char)(v >> 16) & 0xff; p[6] = (u_char)(v >> 8) & 0xff; p[7] = (u_char)v & 0xff; } void put_u32(void *vp, u_int32_t v) { u_char *p = (u_char *)vp; p[0] = (u_char)(v >> 24) & 0xff; p[1] = (u_char)(v >> 16) & 0xff; p[2] = (u_char)(v >> 8) & 0xff; p[3] = (u_char)v & 0xff; } void put_u32_le(void *vp, u_int32_t v) { u_char *p = (u_char *)vp; p[0] = (u_char)v & 0xff; p[1] = (u_char)(v >> 8) & 0xff; p[2] = (u_char)(v >> 16) & 0xff; p[3] = (u_char)(v >> 24) & 0xff; } void put_u16(void *vp, u_int16_t v) { u_char *p = (u_char *)vp; p[0] = (u_char)(v >> 8) & 0xff; p[1] = (u_char)v & 0xff; } void ms_subtract_diff(struct timeval *start, int *ms) { struct timeval diff, finish; gettimeofday(&finish, NULL); timersub(&finish, start, &diff); *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); } void ms_to_timeval(struct timeval *tv, int ms) { if (ms < 0) ms = 0; tv->tv_sec = ms / 1000; tv->tv_usec = (ms % 1000) * 1000; } time_t monotime(void) { #if defined(HAVE_CLOCK_GETTIME) && \ (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) struct timespec ts; static int gettime_failed = 0; if (!gettime_failed) { #if defined(CLOCK_BOOTTIME) if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) return (ts.tv_sec); #endif #if defined(CLOCK_MONOTONIC) if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) return (ts.tv_sec); #endif debug3("clock_gettime: %s", strerror(errno)); gettime_failed = 1; } #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ return time(NULL); } void bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) { bw->buflen = buflen; bw->rate = kbps; bw->thresh = bw->rate; bw->lamt = 0; timerclear(&bw->bwstart); timerclear(&bw->bwend); } /* Callback from read/write loop to insert bandwidth-limiting delays */ void bandwidth_limit(struct bwlimit *bw, size_t read_len) { u_int64_t waitlen; struct timespec ts, rm; if (!timerisset(&bw->bwstart)) { gettimeofday(&bw->bwstart, NULL); return; } bw->lamt += read_len; if (bw->lamt < bw->thresh) return; gettimeofday(&bw->bwend, NULL); timersub(&bw->bwend, &bw->bwstart, &bw->bwend); if (!timerisset(&bw->bwend)) return; bw->lamt *= 8; waitlen = (double)1000000L * bw->lamt / bw->rate; bw->bwstart.tv_sec = waitlen / 1000000L; bw->bwstart.tv_usec = waitlen % 1000000L; if (timercmp(&bw->bwstart, &bw->bwend, >)) { timersub(&bw->bwstart, &bw->bwend, &bw->bwend); /* Adjust the wait time */ if (bw->bwend.tv_sec) { bw->thresh /= 2; if (bw->thresh < bw->buflen / 4) bw->thresh = bw->buflen / 4; } else if (bw->bwend.tv_usec < 10000) { bw->thresh *= 2; if (bw->thresh > bw->buflen * 8) bw->thresh = bw->buflen * 8; } TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); while (nanosleep(&ts, &rm) == -1) { if (errno != EINTR) break; ts = rm; } } bw->lamt = 0; gettimeofday(&bw->bwstart, NULL); } /* Make a template filename for mk[sd]temp() */ void mktemp_proto(char *s, size_t len) { const char *tmpdir; int r; if ((tmpdir = getenv("TMPDIR")) != NULL) { r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); if (r > 0 && (size_t)r < len) return; } r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); if (r < 0 || (size_t)r >= len) fatal("%s: template string too short", __func__); } static const struct { const char *name; int value; } ipqos[] = { { "af11", IPTOS_DSCP_AF11 }, { "af12", IPTOS_DSCP_AF12 }, { "af13", IPTOS_DSCP_AF13 }, { "af21", IPTOS_DSCP_AF21 }, { "af22", IPTOS_DSCP_AF22 }, { "af23", IPTOS_DSCP_AF23 }, { "af31", IPTOS_DSCP_AF31 }, { "af32", IPTOS_DSCP_AF32 }, { "af33", IPTOS_DSCP_AF33 }, { "af41", IPTOS_DSCP_AF41 }, { "af42", IPTOS_DSCP_AF42 }, { "af43", IPTOS_DSCP_AF43 }, { "cs0", IPTOS_DSCP_CS0 }, { "cs1", IPTOS_DSCP_CS1 }, { "cs2", IPTOS_DSCP_CS2 }, { "cs3", IPTOS_DSCP_CS3 }, { "cs4", IPTOS_DSCP_CS4 }, { "cs5", IPTOS_DSCP_CS5 }, { "cs6", IPTOS_DSCP_CS6 }, { "cs7", IPTOS_DSCP_CS7 }, { "ef", IPTOS_DSCP_EF }, { "lowdelay", IPTOS_LOWDELAY }, { "throughput", IPTOS_THROUGHPUT }, { "reliability", IPTOS_RELIABILITY }, { NULL, -1 } }; int parse_ipqos(const char *cp) { u_int i; char *ep; long val; if (cp == NULL) return -1; for (i = 0; ipqos[i].name != NULL; i++) { if (strcasecmp(cp, ipqos[i].name) == 0) return ipqos[i].value; } /* Try parsing as an integer */ val = strtol(cp, &ep, 0); if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) return -1; return val; } const char * iptos2str(int iptos) { int i; static char iptos_str[sizeof "0xff"]; for (i = 0; ipqos[i].name != NULL; i++) { if (ipqos[i].value == iptos) return ipqos[i].name; } snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); return iptos_str; } void lowercase(char *s) { for (; *s; s++) *s = tolower((u_char)*s); } int unix_listener(const char *path, int backlog, int unlink_first) { struct sockaddr_un sunaddr; int saved_errno, sock; memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { error("%s: \"%s\" too long for Unix domain socket", __func__, path); errno = ENAMETOOLONG; return -1; } sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { saved_errno = errno; error("socket: %.100s", strerror(errno)); errno = saved_errno; return -1; } if (unlink_first == 1) { if (unlink(path) != 0 && errno != ENOENT) error("unlink(%s): %.100s", path, strerror(errno)); } if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { saved_errno = errno; error("bind: %.100s", strerror(errno)); close(sock); error("%s: cannot bind to path: %s", __func__, path); errno = saved_errno; return -1; } if (listen(sock, backlog) < 0) { saved_errno = errno; error("listen: %.100s", strerror(errno)); close(sock); unlink(path); error("%s: cannot listen on path: %s", __func__, path); errno = saved_errno; return -1; } return sock; } void sock_set_v6only(int s) { #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) int on = 1; debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); #endif } openssh-7.2p2/misc.h010064400017500001750000000106471267006270000125660ustar00djmdjm/* $OpenBSD: misc.h,v 1.54 2014/07/15 15:54:14 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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 _MISC_H #define _MISC_H /* Data structure for representing a forwarding request. */ struct Forward { char *listen_host; /* Host (address) to listen on. */ int listen_port; /* Port to forward. */ char *listen_path; /* Path to bind domain socket. */ char *connect_host; /* Host to connect. */ int connect_port; /* Port to connect on connect_host. */ char *connect_path; /* Path to connect domain socket. */ int allocated_port; /* Dynamically allocated listen port */ int handle; /* Handle for dynamic listen ports */ }; /* Common server and client forwarding options. */ struct ForwardOptions { int gateway_ports; /* Allow remote connects to forwarded ports. */ mode_t streamlocal_bind_mask; /* umask for streamlocal binds */ int streamlocal_bind_unlink; /* unlink socket before bind */ }; /* misc.c */ char *chop(char *); char *strdelim(char **); int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); int a2tun(const char *, int *); char *put_host_port(const char *, u_short); char *hpdelim(char **); char *cleanhostname(char *); char *colon(char *); long convtime(const char *); char *tilde_expand_filename(const char *, uid_t); char *percent_expand(const char *, ...) __attribute__((__sentinel__)); char *tohex(const void *, size_t); void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); time_t monotime(void); void lowercase(char *s); int unix_listener(const char *, int, int); void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); const char *ssh_gai_strerror(int); typedef struct arglist arglist; struct arglist { char **list; u_int num; u_int nalloc; }; void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); void replacearg(arglist *, u_int, char *, ...) __attribute__((format(printf, 3, 4))); void freeargs(arglist *); int tun_open(int, int); /* Common definitions for ssh tunnel device forwarding */ #define SSH_TUNMODE_NO 0x00 #define SSH_TUNMODE_POINTOPOINT 0x01 #define SSH_TUNMODE_ETHERNET 0x02 #define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT #define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET) #define SSH_TUNID_ANY 0x7fffffff #define SSH_TUNID_ERR (SSH_TUNID_ANY - 1) #define SSH_TUNID_MAX (SSH_TUNID_ANY - 2) /* Fake port to indicate that host field is really a path. */ #define PORT_STREAMLOCAL -2 /* Functions to extract or store big-endian words of various sizes */ u_int64_t get_u64(const void *) __attribute__((__bounded__( __minbytes__, 1, 8))); u_int32_t get_u32(const void *) __attribute__((__bounded__( __minbytes__, 1, 4))); u_int16_t get_u16(const void *) __attribute__((__bounded__( __minbytes__, 1, 2))); void put_u64(void *, u_int64_t) __attribute__((__bounded__( __minbytes__, 1, 8))); void put_u32(void *, u_int32_t) __attribute__((__bounded__( __minbytes__, 1, 4))); void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); /* Little-endian store/load, used by umac.c */ u_int32_t get_u32_le(const void *) __attribute__((__bounded__(__minbytes__, 1, 4))); void put_u32_le(void *, u_int32_t) __attribute__((__bounded__(__minbytes__, 1, 4))); struct bwlimit { size_t buflen; u_int64_t rate, thresh, lamt; struct timeval bwstart, bwend; }; void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); void bandwidth_limit(struct bwlimit *, size_t); int parse_ipqos(const char *); const char *iptos2str(int); void mktemp_proto(char *, size_t); /* readpass.c */ #define RP_ECHO 0x0001 #define RP_ALLOW_STDIN 0x0002 #define RP_ALLOW_EOF 0x0004 #define RP_USE_ASKPASS 0x0008 char *read_passphrase(const char *, int); int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); #endif /* _MISC_H */ openssh-7.2p2/mkinstalldirs010075500017500001750000000012631267006270000142620ustar00djmdjm#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.2 2003/11/21 12:48:55 djm Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here openssh-7.2p2/moduli010064400017500001750000011124441267006270000126750ustar00djmdjm# $OpenBSD: moduli,v 1.14 2015/07/22 02:34:59 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus 20150522025931 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD18DA1F 20150522025936 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD3763B3 20150522025942 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD702B8B 20150522025943 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD77C283 20150522025947 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD96C25B 20150522025953 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADD9B3DB 20150522025956 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADE84F07 20150522025957 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADEC1DB3 20150522030001 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE0E297F 20150522030004 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2A1E23 20150522030005 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2ADE53 20150522030008 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE47B9F7 20150522030009 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE4E1343 20150522030014 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE715CBB 20150522030016 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE7BC9EF 20150522030018 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE84579B 20150522030019 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE8A564B 20150522030023 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEAF7AD7 20150522030025 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEB9DC53 20150522030027 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAECD976F 20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF07F063 20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF08ACBB 20150522030037 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF192C07 20150522030039 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF241333 20150522030040 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF255B3B 20150522030044 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF3DEC37 20150522030048 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF60F05B 20150522030049 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF6255DF 20150522030055 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF8EE01F 20150522030059 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFAD237B 20150522030104 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD13587 20150522030105 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD2BE6F 20150522030108 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFECF32F 20150522030112 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFFDEED7 20150522030115 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01CAA63 20150522030116 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01F3647 20150522030119 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB034B30F 20150522030122 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB04822EF 20150522030124 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0528867 20150522030131 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB08D3CAB 20150522030136 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0B10C6F 20150522030138 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0C688A7 20150522030140 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CCDF9B 20150522030141 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CFD81B 20150522030145 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0F59763 20150522030148 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10339FB 20150522030149 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10E3ACB 20150522030150 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB11127F3 20150522030159 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB15B8BDB 20150522030634 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8ADB54257 20150522030715 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AE6EF847 20150522030737 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AEC5D76B 20150522030739 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AECB604F 20150522030742 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AECF538B 20150522030756 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AF04851B 20150522030828 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8AF867683 20150522030905 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B01F7E27 20150522030909 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B02AFB8F 20150522030918 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B048739F 20150522030930 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B07661CB 20150522030938 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B091EC43 20150522030955 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B0D50D0F 20150522031007 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B1023673 20150522031015 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B119500F 20150522031036 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B177EE9F 20150522031056 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B1D0030B 20150522031103 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B1ECC193 20150522031125 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B24C9CF7 20150522031136 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B2774773 20150522031208 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B2FC9617 20150522031220 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B32FE6CF 20150522031228 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B345AC93 20150522031248 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B392E18F 20150522031256 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B3B32FCF 20150522031300 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B3BF5B2B 20150522031311 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B3E840CB 20150522031316 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B3F5F9D7 20150522031334 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B439F28B 20150522031337 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B44025D3 20150522031339 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B442AC0B 20150522031353 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B4788613 20150522031356 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B47F8FDB 20150522031401 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B48EAEFB 20150522031407 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B4A1CE0B 20150522031420 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B4D73D93 20150522031425 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B4E9937F 20150522031428 2 6 100 2047 5 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B4EFD4BF 20150522031436 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B507149B 20150522031452 2 6 100 2047 2 DB36277B45EA5615C782C08BF6A290A3D61E6B9690E4A147042113FC1BFC0AEEC5FB0FF82FC1FEA86E273F667EC387FEF3421FFFC617A70C34B1987986C6B35C715713914AB75932A3D1942ECC0F324D81BF00D59916B3BFDC7BA432AF5C5DFCF30BF4A2C80B8CA52A9B80E989D3A852BD81A8BD3ADC97497F43C6F0A90882D9CFA165CF1F735C96428BF9BC32A58B71CF1D4FD48A6D2C616E91BB6E07C5CB0DF0C59DAF79D659C6E53007843497BBEE5B341D27DE2E2543B8DFEB4DDAE6328EAD441C3F36509C1FA689FE494B0426ADCAF9E567A1C5A3301689C5CCC55EC4002FAA5D254C2F3C0F8636BEA7019D1CD212B74EE4F273E0B9997720E8B54A3243 20150522032348 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF98368C951B 20150522033023 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9838C4B4F7 20150522033224 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9839729F67 20150522033330 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9839CF938B 20150522033506 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983A5AA27B 20150522033539 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983A849987 20150522033610 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983AAC8A5F 20150522033839 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983B7F9067 20150522033952 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983BE385D7 20150522034001 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983BEA4367 20150522034055 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983C305BC3 20150522034123 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983C516EB3 20150522034146 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983C6D1017 20150522034241 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983CB6A553 20150522034528 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983DA8F54F 20150522034544 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983DB92AEB 20150522034719 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983E32A87B 20150522034748 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983E589F5B 20150522035227 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF983FE4EA2B 20150522035328 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9840340683 20150522035522 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9840D77183 20150522035721 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF98417632BF 20150522035808 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9841B795AB 20150522035847 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9841E9F357 20150522040046 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9842863803 20150522040057 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF98428F98CF 20150522040128 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9842B68EA3 20150522040136 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9842BA209B 20150522040232 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF984303E883 20150522040546 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9844117EF3 20150522040607 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9844276407 20150522040733 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF984499981B 20150522040850 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF984502ECCF 20150522041059 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9845BB3AD7 20150522041141 2 6 100 3071 5 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF9845F34747 20150522041538 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF98473F522B 20150522041645 2 6 100 3071 2 E409DD3E1471472B9A1A2C64FDDC0EB822C4485590288E209141916DF6C51125FCF17ED5F4226F63928FD7E9C60DEC3B0A82C6DF10C33E0CDA2E200004C3B89C7BD872CF9572374C7590F8960C97E1A995319ECABF60C00DAC39A8A4A4196638FB338F47445310F2424518C4ED9C789D17D591DF7B2CB11FC320AD7C84376EF838077C5C81BBEE2BDF38F8716E94F756919654AD5BC8FDF9CD644F0B1F604DFB7CF28B8AD55576458DB547348E74101FA39ADD0D5675E2BA2FA074C2BEC53DCA68A1F49E3F5EBBE9069C7BB20A0ED4217C8D8FE99DC3DDAC05172EB056C6173306F604B90079CEAD87AA170EA89E38C07128067C48695040F766131E9E8459FB71ED94BE176C9F827BBAB219E1BD7A4C7ED9FE7FF62E844B0915C9ACD5B17FDE866EC34C44C348C23CC303D6E7AFDC55AAAC007BF3C67280C13C9801D2D8E0739680257CE5CEBD5CA0CF24D2CA6A354D5D132A72D2ABB2E50D257B5A6DAA038683C1A433861204570824D0734402498259C171BB58DA074D22B1DF98479B35EB 20150522043157 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379177A90103 20150522044043 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379178F7604B 20150522044434 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917986809B 20150522044641 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379179D34D9F 20150522045152 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917A93F48B 20150522045648 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917B4FEA03 20150522051224 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917DA8111B 20150522051844 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917E9226DB 20150522052054 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917EDC16FB 20150522052204 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917F0058A7 20150522052248 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917F16842F 20150522052650 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917FA2234F 20150522052821 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37917FD2EA1B 20150522054416 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F3791823EE827 20150522054652 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379182978693 20150522054912 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379182E6E57B 20150522054941 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379182F0448B 20150522055008 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379182FA0E27 20150522060835 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379185801F93 20150522062202 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379187943813 20150522062512 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F3791880945B7 20150522063933 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918A32FF83 20150522064222 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918A910AB3 20150522064452 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918AE83E73 20150522065035 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918BBA1623 20150522065634 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918C920633 20150522070134 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918D471AAB 20150522070306 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918D7B1063 20150522070332 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918D838D0B 20150522070807 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918E2B8B67 20150522071420 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918F0C3653 20150522071508 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918F1EFFFB 20150522071555 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918F35E697 20150522071903 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37918FA47DEB 20150522074443 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F37919363872B 20150522075339 2 6 100 4095 2 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379194BA4383 20150522080128 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F379195DB3C5F 20150522080506 2 6 100 4095 5 DDE41D7021F9DF8240D0BD8E14CE1E374A4FFDD073767E84C8C347B6F832731277F9D333B8BC7CD96ED164DF5C6F26E46E4BAF0AA7C87B26CE3E11042C1BDDF76095E50D7772E5DC0C48EBA0E41EC92EAFA655DA1B6C614E1F0F9AD815BD7505AA9B8A265D13956B5A26141EE812404DE13B821C9B7BCA9982B8CF7D862F8E8A373FEFEE4AE46EC2122519A2AD896ED18CAECEF314D1B98C83358B6E9D2F3BC58C1688F162E3CF1FF58E57E7B9E14BB37C9C9E9692E57C42937141C226E84C35B42DED9055A7F366A61C3CB4899B499278ED4C729CC1DE54827E882290F9FC13F7F1488F897698EA62A99468D6F3ED0561816C39B8279154FC7A8E453CCC4EB1ABC777A397B694E1B9866C2495489F94721A3351B252D05FE6C7857929B34C19A8EB42ABED88FA370DABCA83A245DC35CFB399824D127507AD540054C647F61C6BD11CAFC3FE5277A1014DF6B538BC8BFE009315BCD60E020DAB840B8A4219EBA4E349680BC7CA3A9BC36164A3D36E325C530B178747814F575899126B307EB63F910DDE0F09E5056B2F9F7E230A42C11DDD34A9B23A64090C2FF9C7F3DD696E6828613E74A64CFC4046ECFA997BE84981430D8A7F8AEC63001E50AF9F556567A0065A9A013A66A2737CEEE468D6A15002358AC648D862B0618E6DD6A98BBBE9E68174D9C9FE4568BB2D12083CF6892B6B8D58307944955A987F3791965094C7 20150522083733 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C514C4F88F 20150522093608 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C517A26827 20150522094040 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C517D03757 20150522095314 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C518686A8B 20150522101845 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C519A641F3 20150522103233 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C51A4A87B7 20150522111208 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C51C3A7B9B 20150522120305 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C51EB16CF7 20150522122813 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C51FE5C353 20150522132032 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5226F04CB 20150522141054 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C524EBC207 20150522153656 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C529553A9F 20150522154114 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5298632F7 20150522154826 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C529DCC5D7 20150522163842 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C52C78C8C3 20150522165625 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C52D5A1C27 20150522172408 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C52EBD88E3 20150522173745 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C52F69630B 20150522184340 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5327AFF1B 20150522190348 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5336CDC63 20150522200705 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5366C1207 20150522201200 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5369D0A6B 20150522202855 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5375B287F 20150522204401 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5380EDB4B 20150522205115 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5385D084B 20150522210056 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C538CEBB3B 20150522212110 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C539B27FE3 20150522215602 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C53B4E825B 20150522222840 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C53CD37713 20150522224719 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C53DAAAE07 20150523005800 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C543D2802B 20150523110456 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C549CAF02F 20150523111755 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C54A5BCB0B 20150523135850 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C551C0E2B7 20150523140345 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C551F4D6B3 20150523153045 2 6 100 6143 2 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C5561141EB 20150523170349 2 6 100 6143 5 E49C8871D7F1191BFDDF2C21369599F9E9F57F502A68C5AA4B87527B218B90EB8F33F3D6B4E379A17BA18BDDA81F2DE8B15EABBF424BDEF329D792093D88EB5536D5F165F767F08AD2220E0005162BB37BE7F45B2574F2BE5BFE4262623C8895A803F747E3BCB0DD396DED524EE1E9B9EEE82C741A1F8ACA2E6DB05CC1FE8C2A7DC50F1F019FD74FC6FFBF38ADA2D36A7CC8DB2C7961C154A74BF0086C173AC7A22B266BBE9974459A7EFDC2F0CDB2F9E288527FD356017FDE01AE17A954561197E18E4AADAF0643860328FC9A2D8A5073348DAD615ADF1AE4AD5BA1630437AB4F7948FCB3D33CD225AA6661DD2AAFFE774CA01F0BF8A2DB168D8FFF3A223E3A60B039E9ABAE8E4B6A37B7E8F77A3EC2D1714B79DEC2ED2BCFB39A4FAAB8913D421099623BCD1DE50B419173236D91E09CFCF544161EB4CA8A45295D812708E349D2118EFA3EDC0F86D3300A80C36D77CEE41441F84BBE663413378F2CAA58F6915B5B3CD799541AD5CCC74B76A59555EDC3B6ABD77318E0A9E6450277DF93A882C6F3D2E13E3BBE361BBB2813A2A269324D7FD2D9437AD065CF3CE698BE08857E5E22800CDBC0235AEB364301AF3170C24B8A68B7B038499F788040E86376DA7DB517751F4FC6D1D3E1C3FE8DDA27B69D1281A18D6D2DC92C2E471A4B577F789E5D397C68B738DBEA06FF55AC1D1C177E3A51D136055E379CF68C27DBB6D66771D9ADFD846CBFF9EFF5B0BDC9EA16A8817243451A93545D19DCFB3DE1E50936A62CD98379ED37C13BE8D71DE48E4115DD309E67F676B0CE88B60BDCD0CAB98878A17E67E20723DE50DB3599485E25687005AB55407632E12AD919498F562D2871A55FEDB76F113D1E92AD5E4D342B45611D9F844BED39B36E5225147D3F6BFEC6C6CA88C423ED62781E29EA9A9418500E7419922E51210FA767153619573EEB19609C77212D6A9724295FBF0A1915F33074D5225E9BD0C6105DA28F1B0E5F43EECBE67B18D5FE74FE60CF87800C623B13FD6152CA913F91ABC5113FF0CCFE362C30DF8F369E08DE8D57222DDF659AE2458C7B4225AE583E178328C55A59DCDF 20150523191201 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB470CDA3203 20150523215157 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4711A72AAB 20150523231527 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47141BE273 20150523235422 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47153C4A8F 20150524010823 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47174C4663 20150524013736 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB471810100B 20150524040115 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB471BEA9823 20150524051719 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB471DEF42C3 20150524055417 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB471EE81B27 20150524104925 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4726B43323 20150524105636 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4726DBBBDF 20150524130121 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB472A1294AB 20150524163025 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB472FBAE453 20150524163715 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB472FE1144B 20150524173410 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47315B458F 20150524181655 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB473268D4BB 20150524223625 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB473917D17B 20150525001303 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB473B95BAC3 20150525011252 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB473D16F0B3 20150525020522 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB473E60DDB7 20150525061910 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4744D20B9F 20150525092924 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47499CAF77 20150525124039 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB474E6A2CEB 20150525132602 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB474F854D7B 20150525170642 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4755495933 20150525201019 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4759D07FB7 20150525223942 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB475D6E1C07 20150525230547 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB475E0B3487 20150525234905 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB475F115D93 20150526002510 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB475FE94D13 20150526014857 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4761E82A83 20150526045853 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB47667CBC4F 20150605090211 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB476DA5F0B7 20150605145212 2 6 100 7679 5 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB4776229827 20150605174343 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB477A770453 20150605182015 2 6 100 7679 2 F829F98FA9F017F2B534A1ADF10BFE7F46E24D09A1EA89D3BB00CC679F6CDF5107A8AAF6F1AC8581E5D52174BA79E05DC2D61FE0B3F10B52520086FF4BE33841858D569DEFF006D6145E062E37CB2A225BAC5207DBC87BBCBE31A12678F8BD3E64FAFD7DA004CA67EED97A92C511BBDB5CAE7D563758EA45BD2280A91209C417093F079E901E48C80702D0B5420C21A571B133299B590EB3ADD67CB1538D85F03C2EBF2A0E1B64C3CCB55CAE257C3939E2A48DDB50B557BFCFFA891EA55D2CE29ADF58D94887170E2EF8EEA14D83117793B2EBEBAA5DAF26F118C53F3F50EF50ACF4BE634C4714F05F198D0A10C91C789C08F9CE84CE238FDFAA6368A1D971450D3A05B279DC0DB0BE57E7B36ED42FC2DE0989CBF4881F59E1C3EB80C8BFA7A9B4493246AB0977F26E368179D4269DF732C935A7901E34042CEBA93FA7B5F2BE7765D1568F83A82D0A556F973DEE714AE348EC6EE73D06E5746D7CA7A2172053350FF03E2B2483F6F5CC20CE2FD44CF81187EE3A28073C4360432BA958FC71C6B4609208610001B762042C20951BB46D484A4D018134E581BAD41EABE16721DB572B76921A6FDA278B4DBCD6E479D89D8F076A3DF39BBF6A81A1529BBDB06A75792E3CC2AE7047533465FB0C4BB6F0B16A2FB13B5812E5AFA8BC06184CB8620700602A9F3D1194EC7F98FF6858CFB26161FA3903301F7F54E8946C688B91631BF8B2452255F7EA8BC66FA9CB2D12BFE8437330956902B5D04469F45AEBEF0CC2F49791EE958B7FC791ACC0BC6A0DAAA8BFB2A5EB49628051F42A0CF1FA0EA33E9EFC8DED03407EA35D1D6E7F09D278793C9E446F99E3A9D6EB93A07FFFA8A16CA1417D776A3DC2D621F3D49A7DED7FC3274228EA72E2BECFBB071B8F1EEC99F04E62DBE9D6F781B3E4078EE28596222A387E87FC7213BB49AFDB79E549B5533877A8FAAD0A86F34AB36B26A48E544F5175EA498E57E6CC8B72924F2DC0B4C4A6364E667B11E49AEF39CE132086650954863BA4BB734A8A13945901802072BF924A6B38BC81E10E3EB74330411F10E259D58C9C4C5F1B4F40E85F11D12D0A5D4F896E24ABBD91E80EBCF0446B189705C133E113699D589068FD67D1993917B9349D380BAAAC594824051275D3AFA8BD3434AAB6C30CC9B6E687AD41A20DBDB890D36571726BCDA2B7051E1BC227480C83F2352A9DF08EBCDEF39936BC26553279246E536F26FFBB65176F4FE67B21658DF22C344A260B4AA8A09F354ECF50B8505F2F6AE4F99F6549CA139B730DC3618E6B5B70966A4276848266CBF23F0FEE469EAF298932EFBBA50E719BFF2259504A6D23938DAD104016FA91EB477B32F0B3 20150526114135 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE95C238093 20150526114600 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE95C32EEF7 20150526134901 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE95F067BA3 20150526153127 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE96179B9CB 20150526164245 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE96332D5AF 20150526174513 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9649A719B 20150527035812 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE97262B7F7 20150527075726 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE977B43343 20150527112120 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE97C1F6EA7 20150528010450 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE98E4FBCCB 20150528020450 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE98F884B93 20150528024708 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE990692277 20150605205801 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE994DC793F 20150606012116 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE99A681C6B 20150606055158 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9A0264EE7 20150606071549 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9A1DB0223 20150606132241 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9A644DC6B 20150606164856 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9AAAAEE73 20150606183208 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9ACEEACDB 20150607015742 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9B6ADF38F 20150607022317 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9B733A2AB 20150607051100 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9BAB79D47 20150607064815 2 6 100 8191 5 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9BCBC8A17 20150607120629 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9C355FA5B 20150607121012 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9C3600A83 20150607123508 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9C3DCB093 20150607144400 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9C680E5AB 20150607145646 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9C6BC5BC3 20150607201140 2 6 100 8191 2 C64DCFC087E26CA2C02394329FAB07FECC446B77A6190D0FFB4326006E0F6D755C35C82228750F80F466E5E6C6FD70A6D4398BBF24C8B4D4B27A38125ADA4D087A7051B2FFCDF675AB1AD9A3A4EE3071B75A8DBEDD879C1B4D396FDF862B2C192B5EB832FA23EAA10DFE795435545882854A0F3BEB476B865E6ED98E43E49950F2FDB00A0E177FAAA3162AE6F513DAFC9A55676C0BC5B87A1C79F98C1A93035F3B39BB24C2C398DA1AADCC16EBB918407579D24ADB3826725E2B4BE73129F28181BD3A1CFCA78712592F8C58E8AF3BA7D7DFFB538AA2476467AC75BFD4C884949C58A0BC8D820E0AE5E0280E083401D239F63649845FEB53444126D137B3A80D4EBF5839263C302FFC3CA5F653B2D93C4AC474D489ADC4E1379BB7FD72950B57EF30FF579917AC9999B4136C030FDCB6121E6F7222227206EBA69DEA5E7DDC7F4718E24E3E4D6D17A81F18E0D376292ED3BB744C66B9ED4BC90F6A04E953B952F794F01372FA88558228C70C97C01D5350EDEE0BEBC99BBD696AE2EFAAB1A0767DCAB15C52821B3243388CE729957668B385A050651F38702C5301A92180A8B84FDF30A74A23E34D9690EEC35A4B644B97DD1558933D7D3DAFF826C942882E223C79EEAE9835F972C273139C396E519D124B6ABBE233548EE1B00B87F7791611DF2E47343368D333C071E231F82914AAE51CEAE790410A6D11D6B82067A9847C945E0BB32310F8370C81636FF68BE65137C3FA912E4C1147F49946C198E1E15E04B8FC7AFFC8465A182E81976C5ED5C2D07F3F6AA25ED27FAC527D6126213BCABC49E102D35AF81E2A694AF0EF83DF6A687E8F3DEEC076BE08A7CD1A3B81C4997136880DB4E7E37B56082F10702F0BB646C7C8A760E297E2A39129BC4A3D0EFB9C3FA2611F5E545F2DC52E013FC49353553F46DEBB59817E18B701689B7A755E609A1B521D72DAE5CBCCE7059E8DA977C97CC87ED8118A2A0011B5ECCCB53785EBDD8986B0A3B36538BBCF4C27DCA06A4B35A9F9920439A35445A0703B34269EB2652999D041912810C06C5742B2AC9B23522D6A2AA3F38A699170B90EAE64509BBD00306C6AFB78AF35EE0D0B504500D5A2AECC0170C2B97620B4796CF538B6D867297F8EC1B08B2F4AFD3534FD9775200BAC298A216AA2553964B7A259D738C84A4035A2BAD35F2AA67CA197D9BB0658ABAB4AF6261C74F18D3D98A5B22C24476FAA8DB9F4FF2621CA01F27C8AB6157F6A1E7F0900CB3F2EEE44D77AAEDC77F24B0E2288340E9A371ACB021407C3E089F61FF0F8469EC9FDFC53892B47CDD0E63748DFE8F814AF7755E6B08491B0CBF8A3A847A922798D28FC72CC9AF8F9299D7B59E1AD1054A98488DB158D471A2D66053FD017238A9B9114393CB4BFD48B8FAABF7E4139E62F533CCCFDD9189E2FFBBB8E488B25B13B17BBEDE9CD3C4A03 openssh-7.2p2/moduli.5010064400017500001750000000071451267006270000130400ustar00djmdjm.\" $OpenBSD: moduli.5,v 1.17 2012/09/26 17:34:38 jmc Exp $ .\" .\" Copyright (c) 2008 Damien Miller .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .Dd $Mdocdate: September 26 2012 $ .Dt MODULI 5 .Os .Sh NAME .Nm moduli .Nd Diffie-Hellman moduli .Sh DESCRIPTION The .Pa /etc/moduli file contains prime numbers and generators for use by .Xr sshd 8 in the Diffie-Hellman Group Exchange key exchange method. .Pp New moduli may be generated with .Xr ssh-keygen 1 using a two-step process. An initial .Em candidate generation pass, using .Ic ssh-keygen -G , calculates numbers that are likely to be useful. A second .Em primality testing pass, using .Ic ssh-keygen -T , provides a high degree of assurance that the numbers are prime and are safe for use in Diffie-Hellman operations by .Xr sshd 8 . This .Nm format is used as the output from each pass. .Pp The file consists of newline-separated records, one per modulus, containing seven space-separated fields. These fields are as follows: .Bl -tag -width Description -offset indent .It timestamp The time that the modulus was last processed as YYYYMMDDHHMMSS. .It type Decimal number specifying the internal structure of the prime modulus. Supported types are: .Pp .Bl -tag -width 0x00 -compact .It 0 Unknown, not tested. .It 2 "Safe" prime; (p-1)/2 is also prime. .It 4 Sophie Germain; 2p+1 is also prime. .El .Pp Moduli candidates initially produced by .Xr ssh-keygen 1 are Sophie Germain primes (type 4). Further primality testing with .Xr ssh-keygen 1 produces safe prime moduli (type 2) that are ready for use in .Xr sshd 8 . Other types are not used by OpenSSH. .It tests Decimal number indicating the type of primality tests that the number has been subjected to represented as a bitmask of the following values: .Pp .Bl -tag -width 0x00 -compact .It 0x00 Not tested. .It 0x01 Composite number \(en not prime. .It 0x02 Sieve of Eratosthenes. .It 0x04 Probabilistic Miller-Rabin primality tests. .El .Pp The .Xr ssh-keygen 1 moduli candidate generation uses the Sieve of Eratosthenes (flag 0x02). Subsequent .Xr ssh-keygen 1 primality tests are Miller-Rabin tests (flag 0x04). .It trials Decimal number indicating the number of primality trials that have been performed on the modulus. .It size Decimal number indicating the size of the prime in bits. .It generator The recommended generator for use with this modulus (hexadecimal). .It modulus The modulus itself in hexadecimal. .El .Pp When performing Diffie-Hellman Group Exchange, .Xr sshd 8 first estimates the size of the modulus required to produce enough Diffie-Hellman output to sufficiently key the selected symmetric cipher. .Xr sshd 8 then randomly selects a modulus from .Fa /etc/moduli that best meets the size requirement. .Sh SEE ALSO .Xr ssh-keygen 1 , .Xr sshd 8 .Sh STANDARDS .Rs .%A M. Friedl .%A N. Provos .%A W. Simpson .%D March 2006 .%R RFC 4419 .%T Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol .%D 2006 .Re openssh-7.2p2/moduli.c010064400017500001750000000507621267006270000131210ustar00djmdjm/* $OpenBSD: moduli.c,v 1.30 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson * Copyright 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. */ /* * Two-step process to generate safe primes for DHGEX * * Sieve candidates for "safe" primes, * suitable for use as Diffie-Hellman moduli; * that is, where q = (p-1)/2 is also prime. * * First step: generate candidate primes (memory intensive) * Second step: test primes' safety (processor intensive) */ #include "includes.h" #ifdef WITH_OPENSSL #include /* MAX */ #include #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "dh.h" #include "log.h" #include "misc.h" #include "openbsd-compat/openssl-compat.h" /* * File output defines */ /* need line long enough for largest moduli plus headers */ #define QLINESIZE (100+8192) /* * Size: decimal. * Specifies the number of the most significant bit (0 to M). * WARNING: internally, usually 1 to N. */ #define QSIZE_MINIMUM (511) /* * Prime sieving defines */ /* Constant: assuming 8 bit bytes and 32 bit words */ #define SHIFT_BIT (3) #define SHIFT_BYTE (2) #define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) #define SHIFT_MEGABYTE (20) #define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) /* * Using virtual memory can cause thrashing. This should be the largest * number that is supported without a large amount of disk activity -- * that would increase the run time from hours to days or weeks! */ #define LARGE_MINIMUM (8UL) /* megabytes */ /* * Do not increase this number beyond the unsigned integer bit size. * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). */ #define LARGE_MAXIMUM (127UL) /* megabytes */ /* * Constant: when used with 32-bit integers, the largest sieve prime * has to be less than 2**32. */ #define SMALL_MAXIMUM (0xffffffffUL) /* Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. */ #define TINY_NUMBER (1UL<<16) /* Ensure enough bit space for testing 2*q. */ #define TEST_MAXIMUM (1UL<<16) #define TEST_MINIMUM (QSIZE_MINIMUM + 1) /* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */ #define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */ /* bit operations on 32-bit words */ #define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31))) #define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31))) #define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31))) /* * Prime testing defines */ /* Minimum number of primality tests to perform */ #define TRIAL_MINIMUM (4) /* * Sieving data (XXX - move to struct) */ /* sieve 2**16 */ static u_int32_t *TinySieve, tinybits; /* sieve 2**30 in 2**16 parts */ static u_int32_t *SmallSieve, smallbits, smallbase; /* sieve relative to the initial value */ static u_int32_t *LargeSieve, largewords, largetries, largenumbers; static u_int32_t largebits, largememory; /* megabytes */ static BIGNUM *largebase; int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); /* * print moduli out in consistent form, */ static int qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries, u_int32_t osize, u_int32_t ogenerator, BIGNUM * omodulus) { struct tm *gtm; time_t time_now; int res; time(&time_now); gtm = gmtime(&time_now); res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ", gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min, gtm->tm_sec, otype, otests, otries, osize, ogenerator); if (res < 0) return (-1); if (BN_print_fp(ofile, omodulus) < 1) return (-1); res = fprintf(ofile, "\n"); fflush(ofile); return (res > 0 ? 0 : -1); } /* ** Sieve p's and q's with small factors */ static void sieve_large(u_int32_t s) { u_int32_t r, u; debug3("sieve_large %u", s); largetries++; /* r = largebase mod s */ r = BN_mod_word(largebase, s); if (r == 0) u = 0; /* s divides into largebase exactly */ else u = s - r; /* largebase+u is first entry divisible by s */ if (u < largebits * 2) { /* * The sieve omits p's and q's divisible by 2, so ensure that * largebase+u is odd. Then, step through the sieve in * increments of 2*s */ if (u & 0x1) u += s; /* Make largebase+u odd, and u even */ /* Mark all multiples of 2*s */ for (u /= 2; u < largebits; u += s) BIT_SET(LargeSieve, u); } /* r = p mod s */ r = (2 * r + 1) % s; if (r == 0) u = 0; /* s divides p exactly */ else u = s - r; /* p+u is first entry divisible by s */ if (u < largebits * 4) { /* * The sieve omits p's divisible by 4, so ensure that * largebase+u is not. Then, step through the sieve in * increments of 4*s */ while (u & 0x3) { if (SMALL_MAXIMUM - u < s) return; u += s; } /* Mark all multiples of 4*s */ for (u /= 4; u < largebits; u += s) BIT_SET(LargeSieve, u); } } /* * list candidates for Sophie-Germain primes (where q = (p-1)/2) * to standard output. * The list is checked against small known primes (less than 2**30). */ int gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) { BIGNUM *q; u_int32_t j, r, s, t; u_int32_t smallwords = TINY_NUMBER >> 6; u_int32_t tinywords = TINY_NUMBER >> 6; time_t time_start, time_stop; u_int32_t i; int ret = 0; largememory = memory; if (memory != 0 && (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { error("Invalid memory amount (min %ld, max %ld)", LARGE_MINIMUM, LARGE_MAXIMUM); return (-1); } /* * Set power to the length in bits of the prime to be generated. * This is changed to 1 less than the desired safe prime moduli p. */ if (power > TEST_MAXIMUM) { error("Too many bits: %u > %lu", power, TEST_MAXIMUM); return (-1); } else if (power < TEST_MINIMUM) { error("Too few bits: %u < %u", power, TEST_MINIMUM); return (-1); } power--; /* decrement before squaring */ /* * The density of ordinary primes is on the order of 1/bits, so the * density of safe primes should be about (1/bits)**2. Set test range * to something well above bits**2 to be reasonably sure (but not * guaranteed) of catching at least one safe prime. */ largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); /* * Need idea of how much memory is available. We don't have to use all * of it. */ if (largememory > LARGE_MAXIMUM) { logit("Limited memory: %u MB; limit %lu MB", largememory, LARGE_MAXIMUM); largememory = LARGE_MAXIMUM; } if (largewords <= (largememory << SHIFT_MEGAWORD)) { logit("Increased memory: %u MB; need %u bytes", largememory, (largewords << SHIFT_BYTE)); largewords = (largememory << SHIFT_MEGAWORD); } else if (largememory > 0) { logit("Decreased memory: %u MB; want %u bytes", largememory, (largewords << SHIFT_BYTE)); largewords = (largememory << SHIFT_MEGAWORD); } TinySieve = xcalloc(tinywords, sizeof(u_int32_t)); tinybits = tinywords << SHIFT_WORD; SmallSieve = xcalloc(smallwords, sizeof(u_int32_t)); smallbits = smallwords << SHIFT_WORD; /* * dynamically determine available memory */ while ((LargeSieve = calloc(largewords, sizeof(u_int32_t))) == NULL) largewords -= (1L << (SHIFT_MEGAWORD - 2)); /* 1/4 MB chunks */ largebits = largewords << SHIFT_WORD; largenumbers = largebits * 2; /* even numbers excluded */ /* validation check: count the number of primes tried */ largetries = 0; if ((q = BN_new()) == NULL) fatal("BN_new failed"); /* * Generate random starting point for subprime search, or use * specified parameter. */ if ((largebase = BN_new()) == NULL) fatal("BN_new failed"); if (start == NULL) { if (BN_rand(largebase, power, 1, 1) == 0) fatal("BN_rand failed"); } else { if (BN_copy(largebase, start) == NULL) fatal("BN_copy: failed"); } /* ensure odd */ if (BN_set_bit(largebase, 0) == 0) fatal("BN_set_bit: failed"); time(&time_start); logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start), largenumbers, power); debug2("start point: 0x%s", BN_bn2hex(largebase)); /* * TinySieve */ for (i = 0; i < tinybits; i++) { if (BIT_TEST(TinySieve, i)) continue; /* 2*i+3 is composite */ /* The next tiny prime */ t = 2 * i + 3; /* Mark all multiples of t */ for (j = i + t; j < tinybits; j += t) BIT_SET(TinySieve, j); sieve_large(t); } /* * Start the small block search at the next possible prime. To avoid * fencepost errors, the last pass is skipped. */ for (smallbase = TINY_NUMBER + 3; smallbase < (SMALL_MAXIMUM - TINY_NUMBER); smallbase += TINY_NUMBER) { for (i = 0; i < tinybits; i++) { if (BIT_TEST(TinySieve, i)) continue; /* 2*i+3 is composite */ /* The next tiny prime */ t = 2 * i + 3; r = smallbase % t; if (r == 0) { s = 0; /* t divides into smallbase exactly */ } else { /* smallbase+s is first entry divisible by t */ s = t - r; } /* * The sieve omits even numbers, so ensure that * smallbase+s is odd. Then, step through the sieve * in increments of 2*t */ if (s & 1) s += t; /* Make smallbase+s odd, and s even */ /* Mark all multiples of 2*t */ for (s /= 2; s < smallbits; s += t) BIT_SET(SmallSieve, s); } /* * SmallSieve */ for (i = 0; i < smallbits; i++) { if (BIT_TEST(SmallSieve, i)) continue; /* 2*i+smallbase is composite */ /* The next small prime */ sieve_large((2 * i) + smallbase); } memset(SmallSieve, 0, smallwords << SHIFT_BYTE); } time(&time_stop); logit("%.24s Sieved with %u small primes in %ld seconds", ctime(&time_stop), largetries, (long) (time_stop - time_start)); for (j = r = 0; j < largebits; j++) { if (BIT_TEST(LargeSieve, j)) continue; /* Definitely composite, skip */ debug2("test q = largebase+%u", 2 * j); if (BN_set_word(q, 2 * j) == 0) fatal("BN_set_word failed"); if (BN_add(q, q, largebase) == 0) fatal("BN_add failed"); if (qfileout(out, MODULI_TYPE_SOPHIE_GERMAIN, MODULI_TESTS_SIEVE, largetries, (power - 1) /* MSB */, (0), q) == -1) { ret = -1; break; } r++; /* count q */ } time(&time_stop); free(LargeSieve); free(SmallSieve); free(TinySieve); logit("%.24s Found %u candidates", ctime(&time_stop), r); return (ret); } static void write_checkpoint(char *cpfile, u_int32_t lineno) { FILE *fp; char tmp[PATH_MAX]; int r; r = snprintf(tmp, sizeof(tmp), "%s.XXXXXXXXXX", cpfile); if (r == -1 || r >= PATH_MAX) { logit("write_checkpoint: temp pathname too long"); return; } if ((r = mkstemp(tmp)) == -1) { logit("mkstemp(%s): %s", tmp, strerror(errno)); return; } if ((fp = fdopen(r, "w")) == NULL) { logit("write_checkpoint: fdopen: %s", strerror(errno)); unlink(tmp); close(r); return; } if (fprintf(fp, "%lu\n", (unsigned long)lineno) > 0 && fclose(fp) == 0 && rename(tmp, cpfile) == 0) debug3("wrote checkpoint line %lu to '%s'", (unsigned long)lineno, cpfile); else logit("failed to write to checkpoint file '%s': %s", cpfile, strerror(errno)); } static unsigned long read_checkpoint(char *cpfile) { FILE *fp; unsigned long lineno = 0; if ((fp = fopen(cpfile, "r")) == NULL) return 0; if (fscanf(fp, "%lu\n", &lineno) < 1) logit("Failed to load checkpoint from '%s'", cpfile); else logit("Loaded checkpoint from '%s' line %lu", cpfile, lineno); fclose(fp); return lineno; } static unsigned long count_lines(FILE *f) { unsigned long count = 0; char lp[QLINESIZE + 1]; if (fseek(f, 0, SEEK_SET) != 0) { debug("input file is not seekable"); return ULONG_MAX; } while (fgets(lp, QLINESIZE + 1, f) != NULL) count++; rewind(f); debug("input file has %lu lines", count); return count; } static char * fmt_time(time_t seconds) { int day, hr, min; static char buf[128]; min = (seconds / 60) % 60; hr = (seconds / 60 / 60) % 24; day = seconds / 60 / 60 / 24; if (day > 0) snprintf(buf, sizeof buf, "%dd %d:%02d", day, hr, min); else snprintf(buf, sizeof buf, "%d:%02d", hr, min); return buf; } static void print_progress(unsigned long start_lineno, unsigned long current_lineno, unsigned long end_lineno) { static time_t time_start, time_prev; time_t time_now, elapsed; unsigned long num_to_process, processed, remaining, percent, eta; double time_per_line; char *eta_str; time_now = monotime(); if (time_start == 0) { time_start = time_prev = time_now; return; } /* print progress after 1m then once per 5m */ if (time_now - time_prev < 5 * 60) return; time_prev = time_now; elapsed = time_now - time_start; processed = current_lineno - start_lineno; remaining = end_lineno - current_lineno; num_to_process = end_lineno - start_lineno; time_per_line = (double)elapsed / processed; /* if we don't know how many we're processing just report count+time */ time(&time_now); if (end_lineno == ULONG_MAX) { logit("%.24s processed %lu in %s", ctime(&time_now), processed, fmt_time(elapsed)); return; } percent = 100 * processed / num_to_process; eta = time_per_line * remaining; eta_str = xstrdup(fmt_time(eta)); logit("%.24s processed %lu of %lu (%lu%%) in %s, ETA %s", ctime(&time_now), processed, num_to_process, percent, fmt_time(elapsed), eta_str); free(eta_str); } /* * perform a Miller-Rabin primality test * on the list of candidates * (checking both q and p) * The result is a list of so-call "safe" primes */ int prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, char *checkpoint_file, unsigned long start_lineno, unsigned long num_lines) { BIGNUM *q, *p, *a; BN_CTX *ctx; char *cp, *lp; u_int32_t count_in = 0, count_out = 0, count_possible = 0; u_int32_t generator_known, in_tests, in_tries, in_type, in_size; unsigned long last_processed = 0, end_lineno; time_t time_start, time_stop; int res; if (trials < TRIAL_MINIMUM) { error("Minimum primality trials is %d", TRIAL_MINIMUM); return (-1); } if (num_lines == 0) end_lineno = count_lines(in); else end_lineno = start_lineno + num_lines; time(&time_start); if ((p = BN_new()) == NULL) fatal("BN_new failed"); if ((q = BN_new()) == NULL) fatal("BN_new failed"); if ((ctx = BN_CTX_new()) == NULL) fatal("BN_CTX_new failed"); debug2("%.24s Final %u Miller-Rabin trials (%x generator)", ctime(&time_start), trials, generator_wanted); if (checkpoint_file != NULL) last_processed = read_checkpoint(checkpoint_file); last_processed = start_lineno = MAX(last_processed, start_lineno); if (end_lineno == ULONG_MAX) debug("process from line %lu from pipe", last_processed); else debug("process from line %lu to line %lu", last_processed, end_lineno); res = 0; lp = xmalloc(QLINESIZE + 1); while (fgets(lp, QLINESIZE + 1, in) != NULL && count_in < end_lineno) { count_in++; if (count_in <= last_processed) { debug3("skipping line %u, before checkpoint or " "specified start line", count_in); continue; } if (checkpoint_file != NULL) write_checkpoint(checkpoint_file, count_in); print_progress(start_lineno, count_in, end_lineno); if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { debug2("%10u: comment or short line", count_in); continue; } /* XXX - fragile parser */ /* time */ cp = &lp[14]; /* (skip) */ /* type */ in_type = strtoul(cp, &cp, 10); /* tests */ in_tests = strtoul(cp, &cp, 10); if (in_tests & MODULI_TESTS_COMPOSITE) { debug2("%10u: known composite", count_in); continue; } /* tries */ in_tries = strtoul(cp, &cp, 10); /* size (most significant bit) */ in_size = strtoul(cp, &cp, 10); /* generator (hex) */ generator_known = strtoul(cp, &cp, 16); /* Skip white space */ cp += strspn(cp, " "); /* modulus (hex) */ switch (in_type) { case MODULI_TYPE_SOPHIE_GERMAIN: debug2("%10u: (%u) Sophie-Germain", count_in, in_type); a = q; if (BN_hex2bn(&a, cp) == 0) fatal("BN_hex2bn failed"); /* p = 2*q + 1 */ if (BN_lshift(p, q, 1) == 0) fatal("BN_lshift failed"); if (BN_add_word(p, 1) == 0) fatal("BN_add_word failed"); in_size += 1; generator_known = 0; break; case MODULI_TYPE_UNSTRUCTURED: case MODULI_TYPE_SAFE: case MODULI_TYPE_SCHNORR: case MODULI_TYPE_STRONG: case MODULI_TYPE_UNKNOWN: debug2("%10u: (%u)", count_in, in_type); a = p; if (BN_hex2bn(&a, cp) == 0) fatal("BN_hex2bn failed"); /* q = (p-1) / 2 */ if (BN_rshift(q, p, 1) == 0) fatal("BN_rshift failed"); break; default: debug2("Unknown prime type"); break; } /* * due to earlier inconsistencies in interpretation, check * the proposed bit size. */ if ((u_int32_t)BN_num_bits(p) != (in_size + 1)) { debug2("%10u: bit size %u mismatch", count_in, in_size); continue; } if (in_size < QSIZE_MINIMUM) { debug2("%10u: bit size %u too short", count_in, in_size); continue; } if (in_tests & MODULI_TESTS_MILLER_RABIN) in_tries += trials; else in_tries = trials; /* * guess unknown generator */ if (generator_known == 0) { if (BN_mod_word(p, 24) == 11) generator_known = 2; else if (BN_mod_word(p, 12) == 5) generator_known = 3; else { u_int32_t r = BN_mod_word(p, 10); if (r == 3 || r == 7) generator_known = 5; } } /* * skip tests when desired generator doesn't match */ if (generator_wanted > 0 && generator_wanted != generator_known) { debug2("%10u: generator %d != %d", count_in, generator_known, generator_wanted); continue; } /* * Primes with no known generator are useless for DH, so * skip those. */ if (generator_known == 0) { debug2("%10u: no known generator", count_in); continue; } count_possible++; /* * The (1/4)^N performance bound on Miller-Rabin is * extremely pessimistic, so don't spend a lot of time * really verifying that q is prime until after we know * that p is also prime. A single pass will weed out the * vast majority of composite q's. */ if (BN_is_prime_ex(q, 1, ctx, NULL) <= 0) { debug("%10u: q failed first possible prime test", count_in); continue; } /* * q is possibly prime, so go ahead and really make sure * that p is prime. If it is, then we can go back and do * the same for q. If p is composite, chances are that * will show up on the first Rabin-Miller iteration so it * doesn't hurt to specify a high iteration count. */ if (!BN_is_prime_ex(p, trials, ctx, NULL)) { debug("%10u: p is not prime", count_in); continue; } debug("%10u: p is almost certainly prime", count_in); /* recheck q more rigorously */ if (!BN_is_prime_ex(q, trials - 1, ctx, NULL)) { debug("%10u: q is not prime", count_in); continue; } debug("%10u: q is almost certainly prime", count_in); if (qfileout(out, MODULI_TYPE_SAFE, in_tests | MODULI_TESTS_MILLER_RABIN, in_tries, in_size, generator_known, p)) { res = -1; break; } count_out++; } time(&time_stop); free(lp); BN_free(p); BN_free(q); BN_CTX_free(ctx); if (checkpoint_file != NULL) unlink(checkpoint_file); logit("%.24s Found %u safe primes of %u candidates in %ld seconds", ctime(&time_stop), count_out, count_possible, (long) (time_stop - time_start)); return (res); } #endif /* WITH_OPENSSL */ openssh-7.2p2/monitor.c010064400017500001750000001443521267006270000133160ustar00djmdjm/* $OpenBSD: monitor.c,v 1.157 2016/02/15 23:32:37 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 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 #include #include "openbsd-compat/sys-tree.h" #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #ifdef HAVE_POLL_H #include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif #ifdef SKEY #include #endif #ifdef WITH_OPENSSL #include #endif #include "openbsd-compat/sys-queue.h" #include "atomicio.h" #include "xmalloc.h" #include "ssh.h" #include "key.h" #include "buffer.h" #include "hostfile.h" #include "auth.h" #include "cipher.h" #include "kex.h" #include "dh.h" #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ #undef TARGET_OS_MAC #include "zlib.h" #define TARGET_OS_MAC 1 #else #include "zlib.h" #endif #include "packet.h" #include "auth-options.h" #include "sshpty.h" #include "channels.h" #include "session.h" #include "sshlogin.h" #include "canohost.h" #include "log.h" #include "misc.h" #include "servconf.h" #include "monitor.h" #include "monitor_mm.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "monitor_fdpass.h" #include "compat.h" #include "ssh2.h" #include "authfd.h" #include "match.h" #include "ssherr.h" #ifdef GSSAPI static Gssctxt *gsscontext = NULL; #endif /* Imports */ extern ServerOptions options; extern u_int utmp_len; extern u_char session_id[]; extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; /* State exported from the child */ static struct sshbuf *child_state; /* Functions on the monitor that answer unprivileged requests */ int mm_answer_moduli(int, Buffer *); int mm_answer_sign(int, Buffer *); int mm_answer_pwnamallow(int, Buffer *); int mm_answer_auth2_read_banner(int, Buffer *); int mm_answer_authserv(int, Buffer *); int mm_answer_authpassword(int, Buffer *); int mm_answer_bsdauthquery(int, Buffer *); int mm_answer_bsdauthrespond(int, Buffer *); int mm_answer_skeyquery(int, Buffer *); int mm_answer_skeyrespond(int, Buffer *); int mm_answer_keyallowed(int, Buffer *); int mm_answer_keyverify(int, Buffer *); int mm_answer_pty(int, Buffer *); int mm_answer_pty_cleanup(int, Buffer *); int mm_answer_term(int, Buffer *); int mm_answer_rsa_keyallowed(int, Buffer *); int mm_answer_rsa_challenge(int, Buffer *); int mm_answer_rsa_response(int, Buffer *); int mm_answer_sesskey(int, Buffer *); int mm_answer_sessid(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); int mm_answer_pam_account(int, Buffer *); int mm_answer_pam_init_ctx(int, Buffer *); int mm_answer_pam_query(int, Buffer *); int mm_answer_pam_respond(int, Buffer *); int mm_answer_pam_free_ctx(int, Buffer *); #endif #ifdef GSSAPI int mm_answer_gss_setup_ctx(int, Buffer *); int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); #endif #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); #endif static int monitor_read_log(struct monitor *); static Authctxt *authctxt; #ifdef WITH_SSH1 static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ #endif /* local state for key verify */ static u_char *key_blob = NULL; static u_int key_bloblen = 0; static int key_blobtype = MM_NOKEY; static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; static char *auth_submethod = NULL; static u_int session_id2_len = 0; static u_char *session_id2 = NULL; static pid_t monitor_child_pid; struct mon_table { enum monitor_reqtype type; int flags; int (*f)(int, Buffer *); }; #define MON_ISAUTH 0x0004 /* Required for Authentication */ #define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ #define MON_ONCE 0x0010 /* Disable after calling */ #define MON_ALOG 0x0020 /* Log auth attempt without authenticating */ #define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) #define MON_PERMIT 0x1000 /* Request is permitted */ struct mon_table mon_dispatch_proto20[] = { #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, #endif #ifdef SKEY {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, #ifdef GSSAPI {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, #endif {0, 0, NULL} }; struct mon_table mon_dispatch_postauth20[] = { #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, 0, mm_answer_sign}, {MONITOR_REQ_PTY, 0, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, #endif {0, 0, NULL} }; struct mon_table mon_dispatch_proto15[] = { #ifdef WITH_SSH1 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed}, {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed}, {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, #endif #ifdef SKEY {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, #endif #endif /* WITH_SSH1 */ {0, 0, NULL} }; struct mon_table mon_dispatch_postauth15[] = { #ifdef WITH_SSH1 {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, #endif #endif /* WITH_SSH1 */ {0, 0, NULL} }; struct mon_table *mon_dispatch; /* Specifies if a certain message is allowed at the moment */ static void monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) { while (ent->f != NULL) { if (ent->type == type) { ent->flags &= ~MON_PERMIT; ent->flags |= permit ? MON_PERMIT : 0; return; } ent++; } } static void monitor_permit_authentications(int permit) { struct mon_table *ent = mon_dispatch; while (ent->f != NULL) { if (ent->flags & MON_AUTH) { ent->flags &= ~MON_PERMIT; ent->flags |= permit ? MON_PERMIT : 0; } ent++; } } void monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) { struct mon_table *ent; int authenticated = 0, partial = 0; debug3("preauth child monitor started"); close(pmonitor->m_recvfd); close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); authctxt->loginmsg = &loginmsg; if (compat20) { mon_dispatch = mon_dispatch_proto20; /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); } else { mon_dispatch = mon_dispatch_proto15; monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); } /* The first few requests do not require asynchronous access */ while (!authenticated) { partial = 0; auth_method = "unknown"; auth_submethod = NULL; authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); /* Special handling for multiple required authentications */ if (options.num_auth_methods != 0) { if (!compat20) fatal("AuthenticationMethods is not supported" "with SSH protocol 1"); if (authenticated && !auth2_update_methods_lists(authctxt, auth_method, auth_submethod)) { debug3("%s: method %s: partial", __func__, auth_method); authenticated = 0; partial = 1; } } if (authenticated) { if (!(ent->flags & MON_AUTHDECIDE)) fatal("%s: unexpected authentication from %d", __func__, ent->type); if (authctxt->pw->pw_uid == 0 && !auth_root_allowed(auth_method)) authenticated = 0; #ifdef USE_PAM /* PAM needs to perform account checks after auth */ if (options.use_pam && authenticated) { Buffer m; buffer_init(&m); mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_PAM_ACCOUNT, &m); authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); buffer_free(&m); } #endif } if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(authctxt, authenticated, partial, auth_method, auth_submethod); if (!partial && !authenticated) authctxt->failures++; } } if (!authctxt->valid) fatal("%s: authenticated invalid user", __func__); if (strcmp(auth_method, "unknown") == 0) fatal("%s: authentication method name unknown", __func__); debug("%s: %s has been authenticated by privileged process", __func__, authctxt->user); mm_get_keystate(pmonitor); /* Drain any buffered messages from the child */ while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) ; close(pmonitor->m_sendfd); close(pmonitor->m_log_recvfd); pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; } static void monitor_set_child_handler(pid_t pid) { monitor_child_pid = pid; } static void monitor_child_handler(int sig) { kill(monitor_child_pid, sig); } void monitor_child_postauth(struct monitor *pmonitor) { close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; monitor_set_child_handler(pmonitor->m_pid); signal(SIGHUP, &monitor_child_handler); signal(SIGTERM, &monitor_child_handler); signal(SIGINT, &monitor_child_handler); #ifdef SIGXFSZ signal(SIGXFSZ, SIG_IGN); #endif if (compat20) { mon_dispatch = mon_dispatch_postauth20; /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); } if (!no_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); } for (;;) monitor_read(pmonitor, mon_dispatch, NULL); } void monitor_sync(struct monitor *pmonitor) { if (options.compression) { /* The member allocation is not visible, so sync it */ mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); } } /* Allocation functions for zlib */ static void * mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) { if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size) fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); return mm_malloc(mm, size * ncount); } static void mm_zfree(struct mm_master *mm, void *address) { mm_free(mm, address); } static int monitor_read_log(struct monitor *pmonitor) { Buffer logmsg; u_int len, level; char *msg; buffer_init(&logmsg); /* Read length */ buffer_append_space(&logmsg, 4); if (atomicio(read, pmonitor->m_log_recvfd, buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { if (errno == EPIPE) { buffer_free(&logmsg); debug("%s: child log fd closed", __func__); close(pmonitor->m_log_recvfd); pmonitor->m_log_recvfd = -1; return -1; } fatal("%s: log fd read: %s", __func__, strerror(errno)); } len = buffer_get_int(&logmsg); if (len <= 4 || len > 8192) fatal("%s: invalid log message length %u", __func__, len); /* Read severity, message */ buffer_clear(&logmsg); buffer_append_space(&logmsg, len); if (atomicio(read, pmonitor->m_log_recvfd, buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) fatal("%s: log fd read: %s", __func__, strerror(errno)); /* Log it */ level = buffer_get_int(&logmsg); msg = buffer_get_string(&logmsg, NULL); if (log_level_name(level) == NULL) fatal("%s: invalid log level %u (corrupted message?)", __func__, level); do_log2(level, "%s [preauth]", msg); buffer_free(&logmsg); free(msg); return 0; } int monitor_read(struct monitor *pmonitor, struct mon_table *ent, struct mon_table **pent) { Buffer m; int ret; u_char type; struct pollfd pfd[2]; for (;;) { memset(&pfd, 0, sizeof(pfd)); pfd[0].fd = pmonitor->m_sendfd; pfd[0].events = POLLIN; pfd[1].fd = pmonitor->m_log_recvfd; pfd[1].events = pfd[1].fd == -1 ? 0 : POLLIN; if (poll(pfd, pfd[1].fd == -1 ? 1 : 2, -1) == -1) { if (errno == EINTR || errno == EAGAIN) continue; fatal("%s: poll: %s", __func__, strerror(errno)); } if (pfd[1].revents) { /* * Drain all log messages before processing next * monitor request. */ monitor_read_log(pmonitor); continue; } if (pfd[0].revents) break; /* Continues below */ } buffer_init(&m); mm_request_receive(pmonitor->m_sendfd, &m); type = buffer_get_char(&m); debug3("%s: checking request %d", __func__, type); while (ent->f != NULL) { if (ent->type == type) break; ent++; } if (ent->f != NULL) { if (!(ent->flags & MON_PERMIT)) fatal("%s: unpermitted request %d", __func__, type); ret = (*ent->f)(pmonitor->m_sendfd, &m); buffer_free(&m); /* The child may use this request only once, disable it */ if (ent->flags & MON_ONCE) { debug2("%s: %d used once, disabling now", __func__, type); ent->flags &= ~MON_PERMIT; } if (pent != NULL) *pent = ent; return ret; } fatal("%s: unsupported request: %d", __func__, type); /* NOTREACHED */ return (-1); } /* allowed key state */ static int monitor_allowed_key(u_char *blob, u_int bloblen) { /* make sure key is allowed */ if (key_blob == NULL || key_bloblen != bloblen || timingsafe_bcmp(key_blob, blob, key_bloblen)) return (0); return (1); } static void monitor_reset_key_state(void) { /* reset state */ free(key_blob); free(hostbased_cuser); free(hostbased_chost); key_blob = NULL; key_bloblen = 0; key_blobtype = MM_NOKEY; hostbased_cuser = NULL; hostbased_chost = NULL; } #ifdef WITH_OPENSSL int mm_answer_moduli(int sock, Buffer *m) { DH *dh; int min, want, max; min = buffer_get_int(m); want = buffer_get_int(m); max = buffer_get_int(m); debug3("%s: got parameters: %d %d %d", __func__, min, want, max); /* We need to check here, too, in case the child got corrupted */ if (max < min || want < min || max < want) fatal("%s: bad parameters: %d %d %d", __func__, min, want, max); buffer_clear(m); dh = choose_dh(min, want, max); if (dh == NULL) { buffer_put_char(m, 0); return (0); } else { /* Send first bignum */ buffer_put_char(m, 1); buffer_put_bignum2(m, dh->p); buffer_put_bignum2(m, dh->g); DH_free(dh); } mm_request_send(sock, MONITOR_ANS_MODULI, m); return (0); } #endif int mm_answer_sign(int sock, Buffer *m) { struct ssh *ssh = active_state; /* XXX */ extern int auth_sock; /* XXX move to state struct? */ struct sshkey *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; char *alg = NULL; size_t datlen, siglen, alglen; int r, keyid, is_proof = 0; const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3("%s", __func__); if ((r = sshbuf_get_u32(m, &keyid)) != 0 || (r = sshbuf_get_string(m, &p, &datlen)) != 0 || (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), * SHA384 (48 bytes) and SHA512 (64 bytes). * * Otherwise, verify the signature request is for a hostkey * proof. * * XXX perform similar check for KEX signature requests too? * it's not trivial, since what is signed is the hash, rather * than the full kex structure... */ if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) { /* * Construct expected hostkey proof and compare it to what * the client sent us. */ if (session_id2_len == 0) /* hostkeys is never first */ fatal("%s: bad data length: %zu", __func__, datlen); if ((key = get_hostkey_public_by_index(keyid, ssh)) == NULL) fatal("%s: no hostkey for index %d", __func__, keyid); if ((sigbuf = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 || (r = sshbuf_put_string(sigbuf, session_id2, session_id2_len)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0) fatal("%s: couldn't prepare private key " "proof buffer: %s", __func__, ssh_err(r)); if (datlen != sshbuf_len(sigbuf) || memcmp(p, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf)) != 0) fatal("%s: bad data length: %zu, hostkey proof len %zu", __func__, datlen, sshbuf_len(sigbuf)); sshbuf_free(sigbuf); is_proof = 1; } /* save session id, it will be passed on the first call */ if (session_id2_len == 0) { session_id2_len = datlen; session_id2 = xmalloc(session_id2_len); memcpy(session_id2, p, session_id2_len); } if ((key = get_hostkey_by_index(keyid)) != NULL) { if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, datafellows)) != 0) fatal("%s: sshkey_sign failed: %s", __func__, ssh_err(r)); } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && auth_sock > 0) { if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, p, datlen, alg, datafellows)) != 0) { fatal("%s: ssh_agent_sign failed: %s", __func__, ssh_err(r)); } } else fatal("%s: no hostkey from index %d", __func__, keyid); debug3("%s: %s signature %p(%zu)", __func__, is_proof ? "KEX" : "hostkey proof", signature, siglen); sshbuf_reset(m); if ((r = sshbuf_put_string(m, signature, siglen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); free(alg); free(p); free(signature); mm_request_send(sock, MONITOR_ANS_SIGN, m); /* Turn on permissions for getpwnam */ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); return (0); } /* Retrieves the password entry and also checks if the user is permitted */ int mm_answer_pwnamallow(int sock, Buffer *m) { char *username; struct passwd *pwent; int allowed = 0; u_int i; debug3("%s", __func__); if (authctxt->attempt++ != 0) fatal("%s: multiple attempts for getpwnam", __func__); username = buffer_get_string(m, NULL); pwent = getpwnamallow(username); authctxt->user = xstrdup(username); setproctitle("%s [priv]", pwent ? username : "unknown"); free(username); buffer_clear(m); if (pwent == NULL) { buffer_put_char(m, 0); authctxt->pw = fakepw(); goto out; } allowed = 1; authctxt->pw = pwent; authctxt->valid = 1; buffer_put_char(m, 1); buffer_put_string(m, pwent, sizeof(struct passwd)); buffer_put_cstring(m, pwent->pw_name); buffer_put_cstring(m, "*"); #ifdef HAVE_STRUCT_PASSWD_PW_GECOS buffer_put_cstring(m, pwent->pw_gecos); #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS buffer_put_cstring(m, pwent->pw_class); #endif buffer_put_cstring(m, pwent->pw_dir); buffer_put_cstring(m, pwent->pw_shell); out: buffer_put_string(m, &options, sizeof(options)); #define M_CP_STROPT(x) do { \ if (options.x != NULL) \ buffer_put_cstring(m, options.x); \ } while (0) #define M_CP_STRARRAYOPT(x, nx) do { \ for (i = 0; i < options.nx; i++) \ buffer_put_cstring(m, options.x[i]); \ } while (0) /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); #undef M_CP_STROPT #undef M_CP_STRARRAYOPT /* Create valid auth method lists */ if (compat20 && auth2_setup_methods_lists(authctxt) != 0) { /* * The monitor will continue long enough to let the child * run to it's packet_disconnect(), but it must not allow any * authentication to succeed. */ debug("%s: no valid authentication method lists", __func__); } debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); mm_request_send(sock, MONITOR_ANS_PWNAM, m); /* For SSHv1 allow authentication now */ if (!compat20) monitor_permit_authentications(1); else { /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); } #ifdef USE_PAM if (options.use_pam) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif return (0); } int mm_answer_auth2_read_banner(int sock, Buffer *m) { char *banner; buffer_clear(m); banner = auth2_read_banner(); buffer_put_cstring(m, banner != NULL ? banner : ""); mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); free(banner); return (0); } int mm_answer_authserv(int sock, Buffer *m) { monitor_permit_authentications(1); authctxt->service = buffer_get_string(m, NULL); authctxt->style = buffer_get_string(m, NULL); debug3("%s: service=%s, style=%s", __func__, authctxt->service, authctxt->style); if (strlen(authctxt->style) == 0) { free(authctxt->style); authctxt->style = NULL; } return (0); } int mm_answer_authpassword(int sock, Buffer *m) { static int call_count; char *passwd; int authenticated; u_int plen; passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && auth_password(authctxt, passwd); explicit_bzero(passwd, strlen(passwd)); free(passwd); buffer_clear(m); buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); call_count++; if (plen == 0 && call_count == 1) auth_method = "none"; else auth_method = "password"; /* Causes monitor loop to terminate if authenticated */ return (authenticated); } #ifdef BSD_AUTH int mm_answer_bsdauthquery(int sock, Buffer *m) { char *name, *infotxt; u_int numprompts; u_int *echo_on; char **prompts; u_int success; success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, &prompts, &echo_on) < 0 ? 0 : 1; buffer_clear(m); buffer_put_int(m, success); if (success) buffer_put_cstring(m, prompts[0]); debug3("%s: sending challenge success: %u", __func__, success); mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); if (success) { free(name); free(infotxt); free(prompts); free(echo_on); } return (0); } int mm_answer_bsdauthrespond(int sock, Buffer *m) { char *response; int authok; if (authctxt->as == NULL) fatal("%s: no bsd auth session", __func__); response = buffer_get_string(m, NULL); authok = options.challenge_response_authentication && auth_userresponse(authctxt->as, response, 0); authctxt->as = NULL; debug3("%s: <%s> = <%d>", __func__, response, authok); free(response); buffer_clear(m); buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); if (compat20) { auth_method = "keyboard-interactive"; auth_submethod = "bsdauth"; } else auth_method = "bsdauth"; return (authok != 0); } #endif #ifdef SKEY int mm_answer_skeyquery(int sock, Buffer *m) { struct skey skey; char challenge[1024]; u_int success; success = _compat_skeychallenge(&skey, authctxt->user, challenge, sizeof(challenge)) < 0 ? 0 : 1; buffer_clear(m); buffer_put_int(m, success); if (success) buffer_put_cstring(m, challenge); debug3("%s: sending challenge success: %u", __func__, success); mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); return (0); } int mm_answer_skeyrespond(int sock, Buffer *m) { char *response; int authok; response = buffer_get_string(m, NULL); authok = (options.challenge_response_authentication && authctxt->valid && skey_haskey(authctxt->pw->pw_name) == 0 && skey_passcheck(authctxt->pw->pw_name, response) != -1); free(response); buffer_clear(m); buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); auth_method = "keyboard-interactive"; auth_submethod = "skey"; return (authok != 0); } #endif #ifdef USE_PAM int mm_answer_pam_start(int sock, Buffer *m) { if (!options.use_pam) fatal("UsePAM not set, but ended up in %s anyway", __func__); start_pam(authctxt); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); return (0); } int mm_answer_pam_account(int sock, Buffer *m) { u_int ret; if (!options.use_pam) fatal("UsePAM not set, but ended up in %s anyway", __func__); ret = do_pam_account(); buffer_put_int(m, ret); buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); return (ret); } static void *sshpam_ctxt, *sshpam_authok; extern KbdintDevice sshpam_device; int mm_answer_pam_init_ctx(int sock, Buffer *m) { debug3("%s", __func__); sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); sshpam_authok = NULL; buffer_clear(m); if (sshpam_ctxt != NULL) { monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); buffer_put_int(m, 1); } else { buffer_put_int(m, 0); } mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); } int mm_answer_pam_query(int sock, Buffer *m) { char *name = NULL, *info = NULL, **prompts = NULL; u_int i, num = 0, *echo_on = 0; int ret; debug3("%s", __func__); sshpam_authok = NULL; ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); if (ret == 0 && num == 0) sshpam_authok = sshpam_ctxt; if (num > 1 || name == NULL || info == NULL) ret = -1; buffer_clear(m); buffer_put_int(m, ret); buffer_put_cstring(m, name); free(name); buffer_put_cstring(m, info); free(info); buffer_put_int(m, num); for (i = 0; i < num; ++i) { buffer_put_cstring(m, prompts[i]); free(prompts[i]); buffer_put_int(m, echo_on[i]); } free(prompts); free(echo_on); auth_method = "keyboard-interactive"; auth_submethod = "pam"; mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); return (0); } int mm_answer_pam_respond(int sock, Buffer *m) { char **resp; u_int i, num; int ret; debug3("%s", __func__); sshpam_authok = NULL; num = buffer_get_int(m); if (num > 0) { resp = xcalloc(num, sizeof(char *)); for (i = 0; i < num; ++i) resp[i] = buffer_get_string(m, NULL); ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); for (i = 0; i < num; ++i) free(resp[i]); free(resp); } else { ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); } buffer_clear(m); buffer_put_int(m, ret); mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); auth_method = "keyboard-interactive"; auth_submethod = "pam"; if (ret == 0) sshpam_authok = sshpam_ctxt; return (0); } int mm_answer_pam_free_ctx(int sock, Buffer *m) { int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; debug3("%s", __func__); (sshpam_device.free_ctx)(sshpam_ctxt); sshpam_ctxt = sshpam_authok = NULL; buffer_clear(m); mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); auth_method = "keyboard-interactive"; auth_submethod = "pam"; return r; } #endif int mm_answer_keyallowed(int sock, Buffer *m) { Key *key; char *cuser, *chost; u_char *blob; u_int bloblen, pubkey_auth_attempt; enum mm_keytype type = 0; int allowed = 0; debug3("%s entering", __func__); type = buffer_get_int(m); cuser = buffer_get_string(m, NULL); chost = buffer_get_string(m, NULL); blob = buffer_get_string(m, &bloblen); pubkey_auth_attempt = buffer_get_int(m); key = key_from_blob(blob, bloblen); if ((compat20 && type == MM_RSAHOSTKEY) || (!compat20 && type != MM_RSAHOSTKEY)) fatal("%s: key type and protocol mismatch", __func__); debug3("%s: key_from_blob: %p", __func__, key); if (key != NULL && authctxt->valid) { /* These should not make it past the privsep child */ if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__); switch (type) { case MM_USERKEY: allowed = options.pubkey_authentication && !auth2_userkey_already_used(authctxt, key) && match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, 0) == 1 && user_key_allowed(authctxt->pw, key, pubkey_auth_attempt); pubkey_auth_info(authctxt, key, NULL); auth_method = "publickey"; if (options.pubkey_authentication && (!pubkey_auth_attempt || allowed != 1)) auth_clear_options(); break; case MM_HOSTKEY: allowed = options.hostbased_authentication && match_pattern_list(sshkey_ssh_name(key), options.hostbased_key_types, 0) == 1 && hostbased_key_allowed(authctxt->pw, cuser, chost, key); pubkey_auth_info(authctxt, key, "client user \"%.100s\", client host \"%.100s\"", cuser, chost); auth_method = "hostbased"; break; #ifdef WITH_SSH1 case MM_RSAHOSTKEY: key->type = KEY_RSA1; /* XXX */ allowed = options.rhosts_rsa_authentication && auth_rhosts_rsa_key_allowed(authctxt->pw, cuser, chost, key); if (options.rhosts_rsa_authentication && allowed != 1) auth_clear_options(); auth_method = "rsa"; break; #endif default: fatal("%s: unknown key type %d", __func__, type); break; } } if (key != NULL) key_free(key); /* clear temporarily storage (used by verify) */ monitor_reset_key_state(); if (allowed) { /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = bloblen; key_blobtype = type; hostbased_cuser = cuser; hostbased_chost = chost; } else { /* Log failed attempt */ auth_log(authctxt, 0, 0, auth_method, NULL); free(blob); free(cuser); free(chost); } debug3("%s: key %p is %s", __func__, key, allowed ? "allowed" : "not allowed"); buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); return (0); } static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; char *p, *userstyle; u_int len; int fail = 0; buffer_init(&b); buffer_append(&b, data, datalen); if (datafellows & SSH_OLD_SESSIONID) { p = buffer_ptr(&b); len = buffer_len(&b); if ((session_id2 == NULL) || (len < session_id2_len) || (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) fail++; buffer_consume(&b, session_id2_len); } else { p = buffer_get_string(&b, &len); if ((session_id2 == NULL) || (len != session_id2_len) || (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) fail++; free(p); } if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); if (strcmp(userstyle, p) != 0) { logit("wrong user name passed to monitor: expected %s != %.100s", userstyle, p); fail++; } free(userstyle); free(p); buffer_skip_string(&b); if (datafellows & SSH_BUG_PKAUTH) { if (!buffer_get_char(&b)) fail++; } else { p = buffer_get_cstring(&b, NULL); if (strcmp("publickey", p) != 0) fail++; free(p); if (!buffer_get_char(&b)) fail++; buffer_skip_string(&b); } buffer_skip_string(&b); if (buffer_len(&b) != 0) fail++; buffer_free(&b); return (fail == 0); } static int monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, char *chost) { Buffer b; char *p, *userstyle; u_int len; int fail = 0; buffer_init(&b); buffer_append(&b, data, datalen); p = buffer_get_string(&b, &len); if ((session_id2 == NULL) || (len != session_id2_len) || (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) fail++; free(p); if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) fail++; p = buffer_get_cstring(&b, NULL); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); if (strcmp(userstyle, p) != 0) { logit("wrong user name passed to monitor: expected %s != %.100s", userstyle, p); fail++; } free(userstyle); free(p); buffer_skip_string(&b); /* service */ p = buffer_get_cstring(&b, NULL); if (strcmp(p, "hostbased") != 0) fail++; free(p); buffer_skip_string(&b); /* pkalg */ buffer_skip_string(&b); /* pkblob */ /* verify client host, strip trailing dot if necessary */ p = buffer_get_string(&b, NULL); if (((len = strlen(p)) > 0) && p[len - 1] == '.') p[len - 1] = '\0'; if (strcmp(p, chost) != 0) fail++; free(p); /* verify client user */ p = buffer_get_string(&b, NULL); if (strcmp(p, cuser) != 0) fail++; free(p); if (buffer_len(&b) != 0) fail++; buffer_free(&b); return (fail == 0); } int mm_answer_keyverify(int sock, Buffer *m) { Key *key; u_char *signature, *data, *blob; u_int signaturelen, datalen, bloblen; int verified = 0; int valid_data = 0; blob = buffer_get_string(m, &bloblen); signature = buffer_get_string(m, &signaturelen); data = buffer_get_string(m, &datalen); if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); key = key_from_blob(blob, bloblen); if (key == NULL) fatal("%s: bad public key blob", __func__); switch (key_blobtype) { case MM_USERKEY: valid_data = monitor_valid_userblob(data, datalen); break; case MM_HOSTKEY: valid_data = monitor_valid_hostbasedblob(data, datalen, hostbased_cuser, hostbased_chost); break; default: valid_data = 0; break; } if (!valid_data) fatal("%s: bad signature data blob", __func__); verified = key_verify(key, signature, signaturelen, data, datalen); debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); /* If auth was successful then record key to ensure it isn't reused */ if (verified == 1 && key_blobtype == MM_USERKEY) auth2_record_userkey(authctxt, key); else key_free(key); free(blob); free(signature); free(data); auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased"; monitor_reset_key_state(); buffer_clear(m); buffer_put_int(m, verified); mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); return (verified == 1); } static void mm_record_login(Session *s, struct passwd *pw) { socklen_t fromlen; struct sockaddr_storage from; if (options.use_login) return; /* * Get IP address of client. If the connection is not a socket, let * the address be 0.0.0.0. */ memset(&from, 0, sizeof(from)); fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } } /* Record that there was a login on that tty from the remote host. */ record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } static void mm_session_close(Session *s) { debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); if (s->ttyfd != -1) { debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } session_unused(s->self); } int mm_answer_pty(int sock, Buffer *m) { extern struct monitor *pmonitor; Session *s; int res, fd0; debug3("%s entering", __func__); buffer_clear(m); s = session_new(); if (s == NULL) goto error; s->authctxt = authctxt; s->pw = authctxt->pw; s->pid = pmonitor->m_pid; res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; pty_setowner(authctxt->pw, s->tty); buffer_put_int(m, 1); buffer_put_cstring(m, s->tty); /* We need to trick ttyslot */ if (dup2(s->ttyfd, 0) == -1) fatal("%s: dup2", __func__); mm_record_login(s, authctxt->pw); /* Now we can close the file descriptor again */ close(0); /* send messages generated by record_login */ buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); buffer_clear(&loginmsg); mm_request_send(sock, MONITOR_ANS_PTY, m); if (mm_send_fd(sock, s->ptyfd) == -1 || mm_send_fd(sock, s->ttyfd) == -1) fatal("%s: send fds failed", __func__); /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); if (fd0 != 0) error("%s: fd0 %d != 0", __func__, fd0); /* slave is not needed */ close(s->ttyfd); s->ttyfd = s->ptyfd; /* no need to dup() because nobody closes ptyfd */ s->ptymaster = s->ptyfd; debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); return (0); error: if (s != NULL) mm_session_close(s); buffer_put_int(m, 0); mm_request_send(sock, MONITOR_ANS_PTY, m); return (0); } int mm_answer_pty_cleanup(int sock, Buffer *m) { Session *s; char *tty; debug3("%s entering", __func__); tty = buffer_get_string(m, NULL); if ((s = session_by_tty(tty)) != NULL) mm_session_close(s); buffer_clear(m); free(tty); return (0); } #ifdef WITH_SSH1 int mm_answer_sesskey(int sock, Buffer *m) { BIGNUM *p; int rsafail; /* Turn off permissions */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0); if ((p = BN_new()) == NULL) fatal("%s: BN_new", __func__); buffer_get_bignum2(m, p); rsafail = ssh1_session_key(p); buffer_clear(m); buffer_put_int(m, rsafail); buffer_put_bignum2(m, p); BN_clear_free(p); mm_request_send(sock, MONITOR_ANS_SESSKEY, m); /* Turn on permissions for sessid passing */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); return (0); } int mm_answer_sessid(int sock, Buffer *m) { int i; debug3("%s entering", __func__); if (buffer_len(m) != 16) fatal("%s: bad ssh1 session id", __func__); for (i = 0; i < 16; i++) session_id[i] = buffer_get_char(m); /* Turn on permissions for getpwnam */ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); return (0); } int mm_answer_rsa_keyallowed(int sock, Buffer *m) { BIGNUM *client_n; Key *key = NULL; u_char *blob = NULL; u_int blen = 0; int allowed = 0; debug3("%s entering", __func__); auth_method = "rsa"; if (options.rsa_authentication && authctxt->valid) { if ((client_n = BN_new()) == NULL) fatal("%s: BN_new", __func__); buffer_get_bignum2(m, client_n); allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); BN_clear_free(client_n); } buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); /* clear temporarily storage (used by generate challenge) */ monitor_reset_key_state(); if (allowed && key != NULL) { key->type = KEY_RSA; /* cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); buffer_put_string(m, blob, blen); /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = blen; key_blobtype = MM_RSAUSERKEY; } if (key != NULL) key_free(key); mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); return (0); } int mm_answer_rsa_challenge(int sock, Buffer *m) { Key *key = NULL; u_char *blob; u_int blen; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); blob = buffer_get_string(m, &blen); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch", __func__); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: received bad key", __func__); if (key->type != KEY_RSA) fatal("%s: received bad key type %d", __func__, key->type); key->type = KEY_RSA1; if (ssh1_challenge) BN_clear_free(ssh1_challenge); ssh1_challenge = auth_rsa_generate_challenge(key); buffer_clear(m); buffer_put_bignum2(m, ssh1_challenge); debug3("%s sending reply", __func__); mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); free(blob); key_free(key); return (0); } int mm_answer_rsa_response(int sock, Buffer *m) { Key *key = NULL; u_char *blob, *response; u_int blen, len; int success; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); if (ssh1_challenge == NULL) fatal("%s: no ssh1_challenge", __func__); blob = buffer_get_string(m, &blen); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch: %d", __func__, key_blobtype); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: received bad key", __func__); response = buffer_get_string(m, &len); if (len != 16) fatal("%s: received bad response to challenge", __func__); success = auth_rsa_verify_response(key, ssh1_challenge, response); free(blob); key_free(key); free(response); auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; /* reset state */ BN_clear_free(ssh1_challenge); ssh1_challenge = NULL; monitor_reset_key_state(); buffer_clear(m); buffer_put_int(m, success); mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); return (success); } #endif int mm_answer_term(int sock, Buffer *req) { extern struct monitor *pmonitor; int res, status; debug3("%s: tearing down sessions", __func__); /* The child is terminating */ session_destroy_all(&mm_session_close); #ifdef USE_PAM if (options.use_pam) sshpam_cleanup(); #endif while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; /* Terminate process */ exit(res); } #ifdef SSH_AUDIT_EVENTS /* Report that an audit event occurred */ int mm_answer_audit_event(int socket, Buffer *m) { ssh_audit_event_t event; debug3("%s entering", __func__); event = buffer_get_int(m); switch(event) { case SSH_AUTH_FAIL_PUBKEY: case SSH_AUTH_FAIL_HOSTBASED: case SSH_AUTH_FAIL_GSSAPI: case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_LOGIN_ROOT_DENIED: case SSH_CONNECTION_CLOSE: case SSH_INVALID_USER: audit_event(event); break; default: fatal("Audit event type %d not permitted", event); } return (0); } int mm_answer_audit_command(int socket, Buffer *m) { u_int len; char *cmd; debug3("%s entering", __func__); cmd = buffer_get_string(m, &len); /* sanity check command, if so how? */ audit_run_command(cmd); free(cmd); return (0); } #endif /* SSH_AUDIT_EVENTS */ void monitor_apply_keystate(struct monitor *pmonitor) { struct ssh *ssh = active_state; /* XXX */ struct kex *kex; int r; debug3("%s: packet_set_state", __func__); if ((r = ssh_packet_set_state(ssh, child_state)) != 0) fatal("%s: packet_set_state: %s", __func__, ssh_err(r)); sshbuf_free(child_state); child_state = NULL; if ((kex = ssh->kex) != NULL) { /* XXX set callbacks */ #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kexecdh_server; # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; kex->sign = sshd_hostkey_sign; } /* Update with new address */ if (options.compression) { ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib, (ssh_packet_comp_alloc_func *)mm_zalloc, (ssh_packet_comp_free_func *)mm_zfree); } } /* This function requries careful sanity checking */ void mm_get_keystate(struct monitor *pmonitor) { debug3("%s: Waiting for new keys", __func__); if ((child_state = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3("%s: GOT new keys", __func__); } /* XXX */ #define FD_CLOSEONEXEC(x) do { \ if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ fatal("fcntl(%d, F_SETFD)", x); \ } while (0) static void monitor_openfds(struct monitor *mon, int do_logfds) { int pair[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) fatal("%s: socketpair: %s", __func__, strerror(errno)); FD_CLOSEONEXEC(pair[0]); FD_CLOSEONEXEC(pair[1]); mon->m_recvfd = pair[0]; mon->m_sendfd = pair[1]; if (do_logfds) { if (pipe(pair) == -1) fatal("%s: pipe: %s", __func__, strerror(errno)); FD_CLOSEONEXEC(pair[0]); FD_CLOSEONEXEC(pair[1]); mon->m_log_recvfd = pair[0]; mon->m_log_sendfd = pair[1]; } else mon->m_log_recvfd = mon->m_log_sendfd = -1; } #define MM_MEMSIZE 65536 struct monitor * monitor_init(void) { struct ssh *ssh = active_state; /* XXX */ struct monitor *mon; mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); /* Used to share zlib space across processes */ if (options.compression) { mon->m_zback = mm_create(NULL, MM_MEMSIZE); mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); /* Compression needs to share state across borders */ ssh_packet_set_compress_hooks(ssh, mon->m_zlib, (ssh_packet_comp_alloc_func *)mm_zalloc, (ssh_packet_comp_free_func *)mm_zfree); } return mon; } void monitor_reinit(struct monitor *mon) { monitor_openfds(mon, 0); } #ifdef GSSAPI int mm_answer_gss_setup_ctx(int sock, Buffer *m) { gss_OID_desc goid; OM_uint32 major; u_int len; goid.elements = buffer_get_string(m, &len); goid.length = len; major = ssh_gssapi_server_ctx(&gsscontext, &goid); free(goid.elements); buffer_clear(m); buffer_put_int(m, major); mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); /* Now we have a context, enable the step */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); return (0); } int mm_answer_gss_accept_ctx(int sock, Buffer *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; OM_uint32 major, minor; OM_uint32 flags = 0; /* GSI needs this */ u_int len; in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); free(in.value); buffer_clear(m); buffer_put_int(m, major); buffer_put_string(m, out.value, out.length); buffer_put_int(m, flags); mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); gss_release_buffer(&minor, &out); if (major == GSS_S_COMPLETE) { monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); } return (0); } int mm_answer_gss_checkmic(int sock, Buffer *m) { gss_buffer_desc gssbuf, mic; OM_uint32 ret; u_int len; gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); mic.length = len; ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); free(gssbuf.value); free(mic.value); buffer_clear(m); buffer_put_int(m, ret); mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); if (!GSS_ERROR(ret)) monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); return (0); } int mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); buffer_clear(m); buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated); } #endif /* GSSAPI */ openssh-7.2p2/monitor.h010064400017500001750000000077461267006270000133300ustar00djmdjm/* $OpenBSD: monitor.h,v 1.19 2015/01/19 19:52:16 markus Exp $ */ /* * Copyright 2002 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 _MONITOR_H_ #define _MONITOR_H_ /* Please keep *_REQ_* values on even numbers and *_ANS_* on odd numbers */ enum monitor_reqtype { MONITOR_REQ_MODULI = 0, MONITOR_ANS_MODULI = 1, MONITOR_REQ_FREE = 2, MONITOR_REQ_AUTHSERV = 4, MONITOR_REQ_SIGN = 6, MONITOR_ANS_SIGN = 7, MONITOR_REQ_PWNAM = 8, MONITOR_ANS_PWNAM = 9, MONITOR_REQ_AUTH2_READ_BANNER = 10, MONITOR_ANS_AUTH2_READ_BANNER = 11, MONITOR_REQ_AUTHPASSWORD = 12, MONITOR_ANS_AUTHPASSWORD = 13, MONITOR_REQ_BSDAUTHQUERY = 14, MONITOR_ANS_BSDAUTHQUERY = 15, MONITOR_REQ_BSDAUTHRESPOND = 16, MONITOR_ANS_BSDAUTHRESPOND = 17, MONITOR_REQ_SKEYQUERY = 18, MONITOR_ANS_SKEYQUERY = 19, MONITOR_REQ_SKEYRESPOND = 20, MONITOR_ANS_SKEYRESPOND = 21, MONITOR_REQ_KEYALLOWED = 22, MONITOR_ANS_KEYALLOWED = 23, MONITOR_REQ_KEYVERIFY = 24, MONITOR_ANS_KEYVERIFY = 25, MONITOR_REQ_KEYEXPORT = 26, MONITOR_REQ_PTY = 28, MONITOR_ANS_PTY = 29, MONITOR_REQ_PTYCLEANUP = 30, MONITOR_REQ_SESSKEY = 32, MONITOR_ANS_SESSKEY = 33, MONITOR_REQ_SESSID = 34, MONITOR_REQ_RSAKEYALLOWED = 36, MONITOR_ANS_RSAKEYALLOWED = 37, MONITOR_REQ_RSACHALLENGE = 38, MONITOR_ANS_RSACHALLENGE = 39, MONITOR_REQ_RSARESPONSE = 40, MONITOR_ANS_RSARESPONSE = 41, MONITOR_REQ_GSSSETUP = 42, MONITOR_ANS_GSSSETUP = 43, MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45, MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, }; struct mm_master; struct monitor { int m_recvfd; int m_sendfd; int m_log_recvfd; int m_log_sendfd; struct mm_master *m_zback; struct mm_master *m_zlib; struct kex **m_pkex; pid_t m_pid; }; struct monitor *monitor_init(void); void monitor_reinit(struct monitor *); void monitor_sync(struct monitor *); struct Authctxt; void monitor_child_preauth(struct Authctxt *, struct monitor *); void monitor_child_postauth(struct monitor *); struct mon_table; int monitor_read(struct monitor*, struct mon_table *, struct mon_table **); /* Prototypes for request sending and receiving */ void mm_request_send(int, enum monitor_reqtype, Buffer *); void mm_request_receive(int, Buffer *); void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *); #endif /* _MONITOR_H_ */ openssh-7.2p2/monitor_fdpass.c010064400017500001750000000113631267006270000146510ustar00djmdjm/* $OpenBSD: monitor_fdpass.c,v 1.20 2015/02/25 23:05:47 djm Exp $ */ /* * Copyright 2001 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 #include #include #ifdef HAVE_SYS_UN_H #include #endif #include #include #include #ifdef HAVE_POLL_H # include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif #include "log.h" #include "monitor_fdpass.h" int mm_send_fd(int sock, int fd) { #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct cmsghdr *cmsg; #endif struct iovec vec; char ch = '\0'; ssize_t n; struct pollfd pfd; memset(&msg, 0, sizeof(msg)); #ifdef HAVE_ACCRIGHTS_IN_MSGHDR msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); #else memset(&cmsgbuf, 0, sizeof(cmsgbuf)); msg.msg_control = (caddr_t)&cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(cmsg) = fd; #endif vec.iov_base = &ch; vec.iov_len = 1; msg.msg_iov = &vec; msg.msg_iovlen = 1; pfd.fd = sock; pfd.events = POLLOUT; while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || errno == EINTR)) { debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); (void)poll(&pfd, 1, -1); } if (n == -1) { error("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); return -1; } if (n != 1) { error("%s: sendmsg: expected sent 1 got %ld", __func__, (long)n); return -1; } return 0; #else error("%s: file descriptor passing not supported", __func__); return -1; #endif } int mm_receive_fd(int sock) { #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct cmsghdr *cmsg; #endif struct iovec vec; ssize_t n; char ch; int fd; struct pollfd pfd; memset(&msg, 0, sizeof(msg)); vec.iov_base = &ch; vec.iov_len = 1; msg.msg_iov = &vec; msg.msg_iovlen = 1; #ifdef HAVE_ACCRIGHTS_IN_MSGHDR msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); #else memset(&cmsgbuf, 0, sizeof(cmsgbuf)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); #endif pfd.fd = sock; pfd.events = POLLIN; while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || errno == EINTR)) { debug3("%s: recvmsg: %s", __func__, strerror(errno)); (void)poll(&pfd, 1, -1); } if (n == -1) { error("%s: recvmsg: %s", __func__, strerror(errno)); return -1; } if (n != 1) { error("%s: recvmsg: expected received 1 got %ld", __func__, (long)n); return -1; } #ifdef HAVE_ACCRIGHTS_IN_MSGHDR if (msg.msg_accrightslen != sizeof(fd)) { error("%s: no fd", __func__); return -1; } #else cmsg = CMSG_FIRSTHDR(&msg); if (cmsg == NULL) { error("%s: no message header", __func__); return -1; } #ifndef BROKEN_CMSG_TYPE if (cmsg->cmsg_type != SCM_RIGHTS) { error("%s: expected type %d got %d", __func__, SCM_RIGHTS, cmsg->cmsg_type); return -1; } #endif fd = (*(int *)CMSG_DATA(cmsg)); #endif return fd; #else error("%s: file descriptor passing not supported", __func__); return -1; #endif } openssh-7.2p2/monitor_fdpass.h010064400017500001750000000027721267006270000146620ustar00djmdjm/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2002 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 _MM_FDPASS_H_ #define _MM_FDPASS_H_ int mm_send_fd(int, int); int mm_receive_fd(int); #endif /* _MM_FDPASS_H_ */ openssh-7.2p2/monitor_mm.c010064400017500001750000000210621267006270000137770ustar00djmdjm/* $OpenBSD: monitor_mm.c,v 1.21 2015/02/06 23:21:59 millert Exp $ */ /* * Copyright 2002 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 #ifdef HAVE_SYS_MMAN_H #include #endif #include "openbsd-compat/sys-tree.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include "xmalloc.h" #include "ssh.h" #include "log.h" #include "monitor_mm.h" static int mm_compare(struct mm_share *a, struct mm_share *b) { ptrdiff_t diff = (char *)a->address - (char *)b->address; if (diff == 0) return (0); else if (diff < 0) return (-1); else return (1); } RB_GENERATE(mmtree, mm_share, next, mm_compare) static struct mm_share * mm_make_entry(struct mm_master *mm, struct mmtree *head, void *address, size_t size) { struct mm_share *tmp, *tmp2; if (mm->mmalloc == NULL) tmp = xcalloc(1, sizeof(struct mm_share)); else tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share)); tmp->address = address; tmp->size = size; tmp2 = RB_INSERT(mmtree, head, tmp); if (tmp2 != NULL) fatal("mm_make_entry(%p): double address %p->%p(%zu)", mm, tmp2, address, size); return (tmp); } /* Creates a shared memory area of a certain size */ struct mm_master * mm_create(struct mm_master *mmalloc, size_t size) { void *address; struct mm_master *mm; if (mmalloc == NULL) mm = xcalloc(1, sizeof(struct mm_master)); else mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); /* * If the memory map has a mm_master it can be completely * shared including authentication between the child * and the client. */ mm->mmalloc = mmalloc; address = xmmap(size); if (address == (void *)MAP_FAILED) fatal("mmap(%zu): %s", size, strerror(errno)); mm->address = address; mm->size = size; RB_INIT(&mm->rb_free); RB_INIT(&mm->rb_allocated); mm_make_entry(mm, &mm->rb_free, address, size); return (mm); } /* Frees either the allocated or the free list */ static void mm_freelist(struct mm_master *mmalloc, struct mmtree *head) { struct mm_share *mms, *next; for (mms = RB_ROOT(head); mms; mms = next) { next = RB_NEXT(mmtree, head, mms); RB_REMOVE(mmtree, head, mms); if (mmalloc == NULL) free(mms); else mm_free(mmalloc, mms); } } /* Destroys a memory mapped area */ void mm_destroy(struct mm_master *mm) { mm_freelist(mm->mmalloc, &mm->rb_free); mm_freelist(mm->mmalloc, &mm->rb_allocated); #ifdef HAVE_MMAP if (munmap(mm->address, mm->size) == -1) fatal("munmap(%p, %zu): %s", mm->address, mm->size, strerror(errno)); #else fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", __func__); #endif if (mm->mmalloc == NULL) free(mm); else mm_free(mm->mmalloc, mm); } void * mm_xmalloc(struct mm_master *mm, size_t size) { void *address; address = mm_malloc(mm, size); if (address == NULL) fatal("%s: mm_malloc(%zu)", __func__, size); memset(address, 0, size); return (address); } /* Allocates data from a memory mapped area */ void * mm_malloc(struct mm_master *mm, size_t size) { struct mm_share *mms, *tmp; if (size == 0) fatal("mm_malloc: try to allocate 0 space"); if (size > SIZE_MAX - MM_MINSIZE + 1) fatal("mm_malloc: size too big"); size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE; RB_FOREACH(mms, mmtree, &mm->rb_free) { if (mms->size >= size) break; } if (mms == NULL) return (NULL); /* Debug */ memset(mms->address, 0xd0, size); tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size); /* Does not change order in RB tree */ mms->size -= size; mms->address = (char *)mms->address + size; if (mms->size == 0) { RB_REMOVE(mmtree, &mm->rb_free, mms); if (mm->mmalloc == NULL) free(mms); else mm_free(mm->mmalloc, mms); } return (tmp->address); } /* Frees memory in a memory mapped area */ void mm_free(struct mm_master *mm, void *address) { struct mm_share *mms, *prev, tmp; tmp.address = address; mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp); if (mms == NULL) fatal("mm_free(%p): can not find %p", mm, address); /* Debug */ memset(mms->address, 0xd0, mms->size); /* Remove from allocated list and insert in free list */ RB_REMOVE(mmtree, &mm->rb_allocated, mms); if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL) fatal("mm_free(%p): double address %p", mm, address); /* Find previous entry */ prev = mms; if (RB_LEFT(prev, next)) { prev = RB_LEFT(prev, next); while (RB_RIGHT(prev, next)) prev = RB_RIGHT(prev, next); } else { if (RB_PARENT(prev, next) && (prev == RB_RIGHT(RB_PARENT(prev, next), next))) prev = RB_PARENT(prev, next); else { while (RB_PARENT(prev, next) && (prev == RB_LEFT(RB_PARENT(prev, next), next))) prev = RB_PARENT(prev, next); prev = RB_PARENT(prev, next); } } /* Check if range does not overlap */ if (prev != NULL && MM_ADDRESS_END(prev) > address) fatal("mm_free: memory corruption: %p(%zu) > %p", prev->address, prev->size, address); /* See if we can merge backwards */ if (prev != NULL && MM_ADDRESS_END(prev) == address) { prev->size += mms->size; RB_REMOVE(mmtree, &mm->rb_free, mms); if (mm->mmalloc == NULL) free(mms); else mm_free(mm->mmalloc, mms); } else prev = mms; if (prev == NULL) return; /* Check if we can merge forwards */ mms = RB_NEXT(mmtree, &mm->rb_free, prev); if (mms == NULL) return; if (MM_ADDRESS_END(prev) > mms->address) fatal("mm_free: memory corruption: %p < %p(%zu)", mms->address, prev->address, prev->size); if (MM_ADDRESS_END(prev) != mms->address) return; prev->size += mms->size; RB_REMOVE(mmtree, &mm->rb_free, mms); if (mm->mmalloc == NULL) free(mms); else mm_free(mm->mmalloc, mms); } static void mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree, struct mm_master *mm, struct mm_master *mmold) { struct mm_master *mmalloc = mm->mmalloc; struct mm_share *mms, *new; /* Sync free list */ RB_FOREACH(mms, mmtree, oldtree) { /* Check the values */ mm_memvalid(mmold, mms, sizeof(struct mm_share)); mm_memvalid(mm, mms->address, mms->size); new = mm_xmalloc(mmalloc, sizeof(struct mm_share)); memcpy(new, mms, sizeof(struct mm_share)); RB_INSERT(mmtree, newtree, new); } } void mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc) { struct mm_master *mm; struct mm_master *mmalloc; struct mm_master *mmold; struct mmtree rb_free, rb_allocated; debug3("%s: Share sync", __func__); mm = *pmm; mmold = mm->mmalloc; mm_memvalid(mmold, mm, sizeof(*mm)); mmalloc = mm_create(NULL, mm->size); mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); memcpy(mm, *pmm, sizeof(struct mm_master)); mm->mmalloc = mmalloc; rb_free = mm->rb_free; rb_allocated = mm->rb_allocated; RB_INIT(&mm->rb_free); RB_INIT(&mm->rb_allocated); mm_sync_list(&rb_free, &mm->rb_free, mm, mmold); mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold); mm_destroy(mmold); *pmm = mm; *pmmalloc = mmalloc; debug3("%s: Share sync end", __func__); } void mm_memvalid(struct mm_master *mm, void *address, size_t size) { void *end = (char *)address + size; if (address < mm->address) fatal("mm_memvalid: address too small: %p", address); if (end < address) fatal("mm_memvalid: end < address: %p < %p", end, address); if (end > MM_ADDRESS_END(mm)) fatal("mm_memvalid: address too large: %p", address); } openssh-7.2p2/monitor_mm.h010064400017500001750000000042321267006270000140040ustar00djmdjm/* $OpenBSD: monitor_mm.h,v 1.6 2014/01/04 17:50:55 tedu Exp $ */ /* * Copyright 2002 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 _MM_H_ #define _MM_H_ struct mm_share { RB_ENTRY(mm_share) next; void *address; size_t size; }; struct mm_master { RB_HEAD(mmtree, mm_share) rb_free; struct mmtree rb_allocated; void *address; size_t size; struct mm_master *mmalloc; /* Used to completely share */ }; RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) #define MM_MINSIZE 128 #define MM_ADDRESS_END(x) (void *)((char *)(x)->address + (x)->size) struct mm_master *mm_create(struct mm_master *, size_t); void mm_destroy(struct mm_master *); void mm_share_sync(struct mm_master **, struct mm_master **); void *mm_malloc(struct mm_master *, size_t); void *mm_xmalloc(struct mm_master *, size_t); void mm_free(struct mm_master *, void *); void mm_memvalid(struct mm_master *, void *, size_t); #endif /* _MM_H_ */ openssh-7.2p2/monitor_wrap.c010064400017500001750000000614361267006270000143500ustar00djmdjm/* $OpenBSD: monitor_wrap.c,v 1.87 2016/01/14 16:17:40 markus Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 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 #include #include #include #include #include #include #include #include #ifdef WITH_OPENSSL #include #include #include #endif #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #ifdef WITH_OPENSSL #include "dh.h" #endif #include "buffer.h" #include "key.h" #include "cipher.h" #include "kex.h" #include "hostfile.h" #include "auth.h" #include "auth-options.h" #include "packet.h" #include "mac.h" #include "log.h" #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ #undef TARGET_OS_MAC #include "zlib.h" #define TARGET_OS_MAC 1 #else #include "zlib.h" #endif #include "monitor.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "atomicio.h" #include "monitor_fdpass.h" #include "misc.h" #include "uuencode.h" #include "channels.h" #include "session.h" #include "servconf.h" #include "ssherr.h" /* Imports */ extern int compat20; extern z_stream incoming_stream; extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer loginmsg; extern ServerOptions options; void mm_log_handler(LogLevel level, const char *msg, void *ctx) { Buffer log_msg; struct monitor *mon = (struct monitor *)ctx; if (mon->m_log_sendfd == -1) fatal("%s: no log channel", __func__); buffer_init(&log_msg); /* * Placeholder for packet length. Will be filled in with the actual * packet length once the packet has been constucted. This saves * fragile math. */ buffer_put_int(&log_msg, 0); buffer_put_int(&log_msg, level); buffer_put_cstring(&log_msg, msg); put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), buffer_len(&log_msg)) != buffer_len(&log_msg)) fatal("%s: write: %s", __func__, strerror(errno)); buffer_free(&log_msg); } int mm_is_monitor(void) { /* * m_pid is only set in the privileged part, and * points to the unprivileged child. */ return (pmonitor && pmonitor->m_pid > 0); } void mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) { u_int mlen = buffer_len(m); u_char buf[5]; debug3("%s entering: type %d", __func__, type); put_u32(buf, mlen + 1); buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) fatal("%s: write: %s", __func__, strerror(errno)); if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) fatal("%s: write: %s", __func__, strerror(errno)); } void mm_request_receive(int sock, Buffer *m) { u_char buf[4]; u_int msg_len; debug3("%s entering", __func__); if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { if (errno == EPIPE) cleanup_exit(255); fatal("%s: read: %s", __func__, strerror(errno)); } msg_len = get_u32(buf); if (msg_len > 256 * 1024) fatal("%s: read: bad msg_len %d", __func__, msg_len); buffer_clear(m); buffer_append_space(m, msg_len); if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) fatal("%s: read: %s", __func__, strerror(errno)); } void mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) { u_char rtype; debug3("%s entering: type %d", __func__, type); mm_request_receive(sock, m); rtype = buffer_get_char(m); if (rtype != type) fatal("%s: read: rtype %d != type %d", __func__, rtype, type); } #ifdef WITH_OPENSSL DH * mm_choose_dh(int min, int nbits, int max) { BIGNUM *p, *g; int success = 0; Buffer m; buffer_init(&m); buffer_put_int(&m, min); buffer_put_int(&m, nbits); buffer_put_int(&m, max); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); success = buffer_get_char(&m); if (success == 0) fatal("%s: MONITOR_ANS_MODULI failed", __func__); if ((p = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); if ((g = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); buffer_get_bignum2(&m, p); buffer_get_bignum2(&m, g); debug3("%s: remaining %d", __func__, buffer_len(&m)); buffer_free(&m); return (dh_new_group(g, p)); } #endif int mm_key_sign(Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen, const char *hostkey_alg) { struct kex *kex = *pmonitor->m_pkex; Buffer m; debug3("%s entering", __func__); buffer_init(&m); buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); buffer_put_string(&m, data, datalen); buffer_put_cstring(&m, hostkey_alg); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); *sigp = buffer_get_string(&m, lenp); buffer_free(&m); return (0); } struct passwd * mm_getpwnamallow(const char *username) { Buffer m; struct passwd *pw; u_int len, i; ServerOptions *newopts; debug3("%s entering", __func__); buffer_init(&m); buffer_put_cstring(&m, username); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); if (buffer_get_char(&m) == 0) { pw = NULL; goto out; } pw = buffer_get_string(&m, &len); if (len != sizeof(struct passwd)) fatal("%s: struct passwd size mismatch", __func__); pw->pw_name = buffer_get_string(&m, NULL); pw->pw_passwd = buffer_get_string(&m, NULL); #ifdef HAVE_STRUCT_PASSWD_PW_GECOS pw->pw_gecos = buffer_get_string(&m, NULL); #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS pw->pw_class = buffer_get_string(&m, NULL); #endif pw->pw_dir = buffer_get_string(&m, NULL); pw->pw_shell = buffer_get_string(&m, NULL); out: /* copy options block as a Match directive may have changed some */ newopts = buffer_get_string(&m, &len); if (len != sizeof(*newopts)) fatal("%s: option block size mismatch", __func__); #define M_CP_STROPT(x) do { \ if (newopts->x != NULL) \ newopts->x = buffer_get_string(&m, NULL); \ } while (0) #define M_CP_STRARRAYOPT(x, nx) do { \ for (i = 0; i < newopts->nx; i++) \ newopts->x[i] = buffer_get_string(&m, NULL); \ } while (0) /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); #undef M_CP_STROPT #undef M_CP_STRARRAYOPT copy_set_server_options(&options, newopts, 1); free(newopts); buffer_free(&m); return (pw); } char * mm_auth2_read_banner(void) { Buffer m; char *banner; debug3("%s entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); buffer_clear(&m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m); banner = buffer_get_string(&m, NULL); buffer_free(&m); /* treat empty banner as missing banner */ if (strlen(banner) == 0) { free(banner); banner = NULL; } return (banner); } /* Inform the privileged process about service and style */ void mm_inform_authserv(char *service, char *style) { Buffer m; debug3("%s entering", __func__); buffer_init(&m); buffer_put_cstring(&m, service); buffer_put_cstring(&m, style ? style : ""); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); buffer_free(&m); } /* Do the password authentication */ int mm_auth_password(Authctxt *authctxt, char *password) { Buffer m; int authenticated = 0; debug3("%s entering", __func__); buffer_init(&m); buffer_put_cstring(&m, password); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); authenticated = buffer_get_int(&m); buffer_free(&m); debug3("%s: user %sauthenticated", __func__, authenticated ? "" : "not "); return (authenticated); } int mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) { return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, pubkey_auth_attempt)); } int mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, Key *key) { return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); } int mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, char *host, Key *key) { int ret; key->type = KEY_RSA; /* XXX hack for key_to_blob */ ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key, 0); key->type = KEY_RSA1; return (ret); } int mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key, int pubkey_auth_attempt) { Buffer m; u_char *blob; u_int len; int allowed = 0, have_forced = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if (!key_to_blob(key, &blob, &len)) return (0); buffer_init(&m); buffer_put_int(&m, type); buffer_put_cstring(&m, user ? user : ""); buffer_put_cstring(&m, host ? host : ""); buffer_put_string(&m, blob, len); buffer_put_int(&m, pubkey_auth_attempt); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); allowed = buffer_get_int(&m); /* fake forced command */ auth_clear_options(); have_forced = buffer_get_int(&m); forced_command = have_forced ? xstrdup("true") : NULL; buffer_free(&m); return (allowed); } /* * This key verify needs to send the key type along, because the * privileged parent makes the decision if the key is allowed * for authentication. */ int mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) { Buffer m; u_char *blob; u_int len; int verified = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if (!key_to_blob(key, &blob, &len)) return (0); buffer_init(&m); buffer_put_string(&m, blob, len); buffer_put_string(&m, sig, siglen); buffer_put_string(&m, data, datalen); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); verified = buffer_get_int(&m); buffer_free(&m); return (verified); } void mm_send_keystate(struct monitor *monitor) { struct ssh *ssh = active_state; /* XXX */ struct sshbuf *m; int r; if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = ssh_packet_get_state(ssh, m)) != 0) fatal("%s: get_state failed: %s", __func__, ssh_err(r)); mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); debug3("%s: Finished sending state", __func__); sshbuf_free(m); } int mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) { Buffer m; char *p, *msg; int success = 0, tmp1 = -1, tmp2 = -1; /* Kludge: ensure there are fds free to receive the pty/tty */ if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || (tmp2 = dup(pmonitor->m_recvfd)) == -1) { error("%s: cannot allocate fds for pty", __func__); if (tmp1 > 0) close(tmp1); if (tmp2 > 0) close(tmp2); return 0; } close(tmp1); close(tmp2); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); debug3("%s: waiting for MONITOR_ANS_PTY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: pty alloc failed", __func__); buffer_free(&m); return (0); } p = buffer_get_string(&m, NULL); msg = buffer_get_string(&m, NULL); buffer_free(&m); strlcpy(namebuf, p, namebuflen); /* Possible truncation */ free(p); buffer_append(&loginmsg, msg, strlen(msg)); free(msg); if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) fatal("%s: receive fds failed", __func__); /* Success */ return (1); } void mm_session_pty_cleanup2(Session *s) { Buffer m; if (s->ttyfd == -1) return; buffer_init(&m); buffer_put_cstring(&m, s->tty); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); buffer_free(&m); /* closed dup'ed master */ if (s->ptymaster != -1 && close(s->ptymaster) < 0) error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; } #ifdef USE_PAM void mm_start_pam(Authctxt *authctxt) { Buffer m; debug3("%s entering", __func__); if (!options.use_pam) fatal("UsePAM=no, but ended up in %s anyway", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); buffer_free(&m); } u_int mm_do_pam_account(void) { Buffer m; u_int ret; char *msg; debug3("%s entering", __func__); if (!options.use_pam) fatal("UsePAM=no, but ended up in %s anyway", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_ACCOUNT, &m); ret = buffer_get_int(&m); msg = buffer_get_string(&m, NULL); buffer_append(&loginmsg, msg, strlen(msg)); free(msg); buffer_free(&m); debug3("%s returning %d", __func__, ret); return (ret); } void * mm_sshpam_init_ctx(Authctxt *authctxt) { Buffer m; int success; debug3("%s", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: pam_init_ctx failed", __func__); buffer_free(&m); return (NULL); } buffer_free(&m); return (authctxt); } int mm_sshpam_query(void *ctx, char **name, char **info, u_int *num, char ***prompts, u_int **echo_on) { Buffer m; u_int i; int ret; debug3("%s", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); ret = buffer_get_int(&m); debug3("%s: pam_query returned %d", __func__, ret); *name = buffer_get_string(&m, NULL); *info = buffer_get_string(&m, NULL); *num = buffer_get_int(&m); if (*num > PAM_MAX_NUM_MSG) fatal("%s: recieved %u PAM messages, expected <= %u", __func__, *num, PAM_MAX_NUM_MSG); *prompts = xcalloc((*num + 1), sizeof(char *)); *echo_on = xcalloc((*num + 1), sizeof(u_int)); for (i = 0; i < *num; ++i) { (*prompts)[i] = buffer_get_string(&m, NULL); (*echo_on)[i] = buffer_get_int(&m); } buffer_free(&m); return (ret); } int mm_sshpam_respond(void *ctx, u_int num, char **resp) { Buffer m; u_int i; int ret; debug3("%s", __func__); buffer_init(&m); buffer_put_int(&m, num); for (i = 0; i < num; ++i) buffer_put_cstring(&m, resp[i]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); ret = buffer_get_int(&m); debug3("%s: pam_respond returned %d", __func__, ret); buffer_free(&m); return (ret); } void mm_sshpam_free_ctx(void *ctxtp) { Buffer m; debug3("%s", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); buffer_free(&m); } #endif /* USE_PAM */ /* Request process termination */ void mm_terminate(void) { Buffer m; buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); buffer_free(&m); } #ifdef WITH_SSH1 int mm_ssh1_session_key(BIGNUM *num) { int rsafail; Buffer m; buffer_init(&m); buffer_put_bignum2(&m, num); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); rsafail = buffer_get_int(&m); buffer_get_bignum2(&m, num); buffer_free(&m); return (rsafail); } #endif static void mm_chall_setup(char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) { *name = xstrdup(""); *infotxt = xstrdup(""); *numprompts = 1; *prompts = xcalloc(*numprompts, sizeof(char *)); *echo_on = xcalloc(*numprompts, sizeof(u_int)); (*echo_on)[0] = 0; } int mm_bsdauth_query(void *ctx, char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) { Buffer m; u_int success; char *challenge; debug3("%s: entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: no challenge", __func__); buffer_free(&m); return (-1); } /* Get the challenge, and format the response */ challenge = buffer_get_string(&m, NULL); buffer_free(&m); mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); (*prompts)[0] = challenge; debug3("%s: received challenge: %s", __func__, challenge); return (0); } int mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) { Buffer m; int authok; debug3("%s: entering", __func__); if (numresponses != 1) return (-1); buffer_init(&m); buffer_put_cstring(&m, responses[0]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHRESPOND, &m); authok = buffer_get_int(&m); buffer_free(&m); return ((authok == 0) ? -1 : 0); } #ifdef SKEY int mm_skey_query(void *ctx, char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) { Buffer m; u_int success; char *challenge; debug3("%s: entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: no challenge", __func__); buffer_free(&m); return (-1); } /* Get the challenge, and format the response */ challenge = buffer_get_string(&m, NULL); buffer_free(&m); debug3("%s: received challenge: %s", __func__, challenge); mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); free(challenge); return (0); } int mm_skey_respond(void *ctx, u_int numresponses, char **responses) { Buffer m; int authok; debug3("%s: entering", __func__); if (numresponses != 1) return (-1); buffer_init(&m); buffer_put_cstring(&m, responses[0]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYRESPOND, &m); authok = buffer_get_int(&m); buffer_free(&m); return ((authok == 0) ? -1 : 0); } #endif /* SKEY */ void mm_ssh1_session_id(u_char session_id[16]) { Buffer m; int i; debug3("%s entering", __func__); buffer_init(&m); for (i = 0; i < 16; i++) buffer_put_char(&m, session_id[i]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); buffer_free(&m); } #ifdef WITH_SSH1 int mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) { Buffer m; Key *key; u_char *blob; u_int blen; int allowed = 0, have_forced = 0; debug3("%s entering", __func__); buffer_init(&m); buffer_put_bignum2(&m, client_n); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); allowed = buffer_get_int(&m); /* fake forced command */ auth_clear_options(); have_forced = buffer_get_int(&m); forced_command = have_forced ? xstrdup("true") : NULL; if (allowed && rkey != NULL) { blob = buffer_get_string(&m, &blen); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: key_from_blob failed", __func__); *rkey = key; free(blob); } buffer_free(&m); return (allowed); } BIGNUM * mm_auth_rsa_generate_challenge(Key *key) { Buffer m; BIGNUM *challenge; u_char *blob; u_int blen; debug3("%s entering", __func__); if ((challenge = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); key->type = KEY_RSA; /* XXX cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); key->type = KEY_RSA1; buffer_init(&m); buffer_put_string(&m, blob, blen); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); buffer_get_bignum2(&m, challenge); buffer_free(&m); return (challenge); } int mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) { Buffer m; u_char *blob; u_int blen; int success = 0; debug3("%s entering", __func__); key->type = KEY_RSA; /* XXX cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); key->type = KEY_RSA1; buffer_init(&m); buffer_put_string(&m, blob, blen); buffer_put_string(&m, response, 16); free(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); success = buffer_get_int(&m); buffer_free(&m); return (success); } #endif #ifdef SSH_AUDIT_EVENTS void mm_audit_event(ssh_audit_event_t event) { Buffer m; debug3("%s entering", __func__); buffer_init(&m); buffer_put_int(&m, event); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); buffer_free(&m); } void mm_audit_run_command(const char *command) { Buffer m; debug3("%s entering command %s", __func__, command); buffer_init(&m); buffer_put_cstring(&m, command); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); buffer_free(&m); } #endif /* SSH_AUDIT_EVENTS */ #ifdef GSSAPI OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) { Buffer m; OM_uint32 major; /* Client doesn't get to see the context */ *ctx = NULL; buffer_init(&m); buffer_put_string(&m, goid->elements, goid->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); major = buffer_get_int(&m); buffer_free(&m); return (major); } OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, gss_buffer_desc *out, OM_uint32 *flags) { Buffer m; OM_uint32 major; u_int len; buffer_init(&m); buffer_put_string(&m, in->value, in->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); major = buffer_get_int(&m); out->value = buffer_get_string(&m, &len); out->length = len; if (flags) *flags = buffer_get_int(&m); buffer_free(&m); return (major); } OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) { Buffer m; OM_uint32 major; buffer_init(&m); buffer_put_string(&m, gssbuf->value, gssbuf->length); buffer_put_string(&m, gssmic->value, gssmic->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, &m); major = buffer_get_int(&m); buffer_free(&m); return(major); } int mm_ssh_gssapi_userok(char *user) { Buffer m; int authenticated = 0; buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, &m); authenticated = buffer_get_int(&m); buffer_free(&m); debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } #endif /* GSSAPI */ openssh-7.2p2/monitor_wrap.h010064400017500001750000000100001267006270000143320ustar00djmdjm/* $OpenBSD: monitor_wrap.h,v 1.29 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright 2002 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 _MM_WRAP_H_ #define _MM_WRAP_H_ extern int use_privsep; #define PRIVSEP(x) (use_privsep ? mm_##x : x) enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY}; struct monitor; struct mm_master; struct Authctxt; void mm_log_handler(LogLevel, const char *, void *); int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); void mm_inform_authserv(char *, char *); struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct Authctxt *, char *); int mm_key_allowed(enum mm_keytype, char *, char *, Key *, int); int mm_user_key_allowed(struct passwd *, Key *, int); int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); BIGNUM *mm_auth_rsa_generate_challenge(Key *); #ifdef GSSAPI OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); int mm_ssh_gssapi_userok(char *user); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); #endif #ifdef USE_PAM void mm_start_pam(struct Authctxt *); u_int mm_do_pam_account(void); void *mm_sshpam_init_ctx(struct Authctxt *); int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_sshpam_respond(void *, u_int, char **); void mm_sshpam_free_ctx(void *); #endif #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(ssh_audit_event_t); void mm_audit_run_command(const char *); #endif struct Session; void mm_terminate(void); int mm_pty_allocate(int *, int *, char *, size_t); void mm_session_pty_cleanup2(struct Session *); /* SSHv1 interfaces */ void mm_ssh1_session_id(u_char *); int mm_ssh1_session_key(BIGNUM *); /* Key export functions */ struct newkeys *mm_newkeys_from_blob(u_char *, int); int mm_newkeys_to_blob(int, u_char **, u_int *); void monitor_apply_keystate(struct monitor *); void mm_get_keystate(struct monitor *); void mm_send_keystate(struct monitor*); /* bsdauth */ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_bsdauth_respond(void *, u_int, char **); /* skey */ int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); /* zlib allocation hooks */ void mm_init_compression(struct mm_master *); #endif /* _MM_WRAP_H_ */ openssh-7.2p2/msg.c010064400017500001750000000054021267006270000124050ustar00djmdjm/* $OpenBSD: msg.c,v 1.16 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #include #include #include #include #include #include "sshbuf.h" #include "ssherr.h" #include "log.h" #include "atomicio.h" #include "msg.h" #include "misc.h" int ssh_msg_send(int fd, u_char type, struct sshbuf *m) { u_char buf[5]; u_int mlen = sshbuf_len(m); debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff); put_u32(buf, mlen + 1); buf[4] = type; /* 1st byte of payload is mesg-type */ if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) { error("ssh_msg_send: write"); return (-1); } if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(m), mlen) != mlen) { error("ssh_msg_send: write"); return (-1); } return (0); } int ssh_msg_recv(int fd, struct sshbuf *m) { u_char buf[4], *p; u_int msg_len; int r; debug3("ssh_msg_recv entering"); if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) { if (errno != EPIPE) error("ssh_msg_recv: read: header"); return (-1); } msg_len = get_u32(buf); if (msg_len > 256 * 1024) { error("ssh_msg_recv: read: bad msg_len %u", msg_len); return (-1); } sshbuf_reset(m); if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); return -1; } if (atomicio(read, fd, p, msg_len) != msg_len) { error("ssh_msg_recv: read: %s", strerror(errno)); return (-1); } return (0); } openssh-7.2p2/msg.h010064400017500001750000000027641267006270000124220ustar00djmdjm/* $OpenBSD: msg.h,v 1.5 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SSH_MSG_H #define SSH_MSG_H struct sshbuf; int ssh_msg_send(int, u_char, struct sshbuf *); int ssh_msg_recv(int, struct sshbuf *); #endif openssh-7.2p2/mux.c010064400017500001750000001642151267006270000124400ustar00djmdjm/* $OpenBSD: mux.c,v 1.58 2016/01/13 23:04:47 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ssh session multiplexing support */ /* * TODO: * - Better signalling from master to slave, especially passing of * error messages * - Better fall-back from mux slave error to new connection. * - ExitOnForwardingFailure * - Maybe extension mechanisms for multi-X11/multi-agent forwarding * - Support ~^Z in mux slaves. * - Inspect or control sessions in master. * - If we ever support the "signal" channel request, send signals on * sessions in master. */ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #ifdef HAVE_POLL_H #include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif #ifdef HAVE_UTIL_H # include #endif #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "log.h" #include "ssh.h" #include "ssh2.h" #include "pathnames.h" #include "misc.h" #include "match.h" #include "buffer.h" #include "channels.h" #include "msg.h" #include "packet.h" #include "monitor_fdpass.h" #include "sshpty.h" #include "key.h" #include "readconf.h" #include "clientloop.h" /* from ssh.c */ extern int tty_flag; extern Options options; extern int stdin_null_flag; extern char *host; extern int subsystem_flag; extern Buffer command; extern volatile sig_atomic_t quit_pending; extern char *stdio_forward_host; extern int stdio_forward_port; /* Context for session open confirmation callback */ struct mux_session_confirm_ctx { u_int want_tty; u_int want_subsys; u_int want_x_fwd; u_int want_agent_fwd; Buffer cmd; char *term; struct termios tio; char **env; u_int rid; }; /* Context for stdio fwd open confirmation callback */ struct mux_stdio_confirm_ctx { u_int rid; }; /* Context for global channel callback */ struct mux_channel_confirm_ctx { u_int cid; /* channel id */ u_int rid; /* request id */ int fid; /* forward id */ }; /* fd to control socket */ int muxserver_sock = -1; /* client request id */ u_int muxclient_request_id = 0; /* Multiplexing control command */ u_int muxclient_command = 0; /* Set when signalled. */ static volatile sig_atomic_t muxclient_terminate = 0; /* PID of multiplex server */ static u_int muxserver_pid = 0; static Channel *mux_listener_channel = NULL; struct mux_master_state { int hello_rcvd; }; /* mux protocol messages */ #define MUX_MSG_HELLO 0x00000001 #define MUX_C_NEW_SESSION 0x10000002 #define MUX_C_ALIVE_CHECK 0x10000004 #define MUX_C_TERMINATE 0x10000005 #define MUX_C_OPEN_FWD 0x10000006 #define MUX_C_CLOSE_FWD 0x10000007 #define MUX_C_NEW_STDIO_FWD 0x10000008 #define MUX_C_STOP_LISTENING 0x10000009 #define MUX_S_OK 0x80000001 #define MUX_S_PERMISSION_DENIED 0x80000002 #define MUX_S_FAILURE 0x80000003 #define MUX_S_EXIT_MESSAGE 0x80000004 #define MUX_S_ALIVE 0x80000005 #define MUX_S_SESSION_OPENED 0x80000006 #define MUX_S_REMOTE_PORT 0x80000007 #define MUX_S_TTY_ALLOC_FAIL 0x80000008 /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ #define MUX_FWD_LOCAL 1 #define MUX_FWD_REMOTE 2 #define MUX_FWD_DYNAMIC 3 static void mux_session_confirm(int, int, void *); static void mux_stdio_confirm(int, int, void *); static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); static const struct { u_int type; int (*handler)(u_int, Channel *, Buffer *, Buffer *); } mux_master_handlers[] = { { MUX_MSG_HELLO, process_mux_master_hello }, { MUX_C_NEW_SESSION, process_mux_new_session }, { MUX_C_ALIVE_CHECK, process_mux_alive_check }, { MUX_C_TERMINATE, process_mux_terminate }, { MUX_C_OPEN_FWD, process_mux_open_fwd }, { MUX_C_CLOSE_FWD, process_mux_close_fwd }, { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, { MUX_C_STOP_LISTENING, process_mux_stop_listening }, { 0, NULL } }; /* Cleanup callback fired on closure of mux slave _session_ channel */ /* ARGSUSED */ static void mux_master_session_cleanup_cb(int cid, void *unused) { Channel *cc, *c = channel_by_id(cid); debug3("%s: entering for channel %d", __func__, cid); if (c == NULL) fatal("%s: channel_by_id(%i) == NULL", __func__, cid); if (c->ctl_chan != -1) { if ((cc = channel_by_id(c->ctl_chan)) == NULL) fatal("%s: channel %d missing control channel %d", __func__, c->self, c->ctl_chan); c->ctl_chan = -1; cc->remote_id = -1; chan_rcvd_oclose(cc); } channel_cancel_cleanup(c->self); } /* Cleanup callback fired on closure of mux slave _control_ channel */ /* ARGSUSED */ static void mux_master_control_cleanup_cb(int cid, void *unused) { Channel *sc, *c = channel_by_id(cid); debug3("%s: entering for channel %d", __func__, cid); if (c == NULL) fatal("%s: channel_by_id(%i) == NULL", __func__, cid); if (c->remote_id != -1) { if ((sc = channel_by_id(c->remote_id)) == NULL) fatal("%s: channel %d missing session channel %d", __func__, c->self, c->remote_id); c->remote_id = -1; sc->ctl_chan = -1; if (sc->type != SSH_CHANNEL_OPEN && sc->type != SSH_CHANNEL_OPENING) { debug2("%s: channel %d: not open", __func__, sc->self); chan_mark_dead(sc); } else { if (sc->istate == CHAN_INPUT_OPEN) chan_read_failed(sc); if (sc->ostate == CHAN_OUTPUT_OPEN) chan_write_failed(sc); } } channel_cancel_cleanup(c->self); } /* Check mux client environment variables before passing them to mux master. */ static int env_permitted(char *env) { int i, ret; char name[1024], *cp; if ((cp = strchr(env, '=')) == NULL || cp == env) return 0; ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); if (ret <= 0 || (size_t)ret >= sizeof(name)) { error("env_permitted: name '%.100s...' too long", env); return 0; } for (i = 0; i < options.num_send_env; i++) if (match_pattern(name, options.send_env[i])) return 1; return 0; } /* Mux master protocol message handlers */ static int process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) { u_int ver; struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; if (state == NULL) fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self); if (state->hello_rcvd) { error("%s: HELLO received twice", __func__); return -1; } if (buffer_get_int_ret(&ver, m) != 0) { malf: error("%s: malformed message", __func__); return -1; } if (ver != SSHMUX_VER) { error("Unsupported multiplexing protocol version %d " "(expected %d)", ver, SSHMUX_VER); return -1; } debug2("%s: channel %d slave version %u", __func__, c->self, ver); /* No extensions are presently defined */ while (buffer_len(m) > 0) { char *name = buffer_get_string_ret(m, NULL); char *value = buffer_get_string_ret(m, NULL); if (name == NULL || value == NULL) { free(name); free(value); goto malf; } debug2("Unrecognised slave extension \"%s\"", name); free(name); free(value); } state->hello_rcvd = 1; return 0; } static int process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) { Channel *nc; struct mux_session_confirm_ctx *cctx; char *reserved, *cmd, *cp; u_int i, j, len, env_len, escape_char, window, packetmax; int new_fd[3]; /* Reply for SSHMUX_COMMAND_OPEN */ cctx = xcalloc(1, sizeof(*cctx)); cctx->term = NULL; cctx->rid = rid; cmd = reserved = NULL; cctx->env = NULL; env_len = 0; if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&cctx->want_tty, m) != 0 || buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 || buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 || buffer_get_int_ret(&cctx->want_subsys, m) != 0 || buffer_get_int_ret(&escape_char, m) != 0 || (cctx->term = buffer_get_string_ret(m, &len)) == NULL || (cmd = buffer_get_string_ret(m, &len)) == NULL) { malf: free(cmd); free(reserved); for (j = 0; j < env_len; j++) free(cctx->env[j]); free(cctx->env); free(cctx->term); free(cctx); error("%s: malformed message", __func__); return -1; } free(reserved); reserved = NULL; while (buffer_len(m) > 0) { #define MUX_MAX_ENV_VARS 4096 if ((cp = buffer_get_string_ret(m, &len)) == NULL) goto malf; if (!env_permitted(cp)) { free(cp); continue; } cctx->env = xreallocarray(cctx->env, env_len + 2, sizeof(*cctx->env)); cctx->env[env_len++] = cp; cctx->env[env_len] = NULL; if (env_len > MUX_MAX_ENV_VARS) { error(">%d environment variables received, ignoring " "additional", MUX_MAX_ENV_VARS); break; } } debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, " "term \"%s\", cmd \"%s\", env %u", __func__, c->self, cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd, cctx->want_subsys, cctx->term, cmd, env_len); buffer_init(&cctx->cmd); buffer_append(&cctx->cmd, cmd, strlen(cmd)); free(cmd); cmd = NULL; /* Gather fds from client */ for(i = 0; i < 3; i++) { if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) { error("%s: failed to receive fd %d from slave", __func__, i); for (j = 0; j < i; j++) close(new_fd[j]); for (j = 0; j < env_len; j++) free(cctx->env[j]); free(cctx->env); free(cctx->term); buffer_free(&cctx->cmd); free(cctx); /* prepare reply */ buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "did not receive file descriptors"); return -1; } } debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__, new_fd[0], new_fd[1], new_fd[2]); /* XXX support multiple child sessions in future */ if (c->remote_id != -1) { debug2("%s: session already open", __func__); /* prepare reply */ buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "Multiple sessions not supported"); cleanup: close(new_fd[0]); close(new_fd[1]); close(new_fd[2]); free(cctx->term); if (env_len != 0) { for (i = 0; i < env_len; i++) free(cctx->env[i]); free(cctx->env); } buffer_free(&cctx->cmd); free(cctx); return 0; } if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Allow shared connection to %s? ", host)) { debug2("%s: session refused by user", __func__); /* prepare reply */ buffer_put_int(r, MUX_S_PERMISSION_DENIED); buffer_put_int(r, rid); buffer_put_cstring(r, "Permission denied"); goto cleanup; } } /* Try to pick up ttymodes from client before it goes raw */ if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) error("%s: tcgetattr: %s", __func__, strerror(errno)); /* enable nonblocking unless tty */ if (!isatty(new_fd[0])) set_nonblock(new_fd[0]); if (!isatty(new_fd[1])) set_nonblock(new_fd[1]); if (!isatty(new_fd[2])) set_nonblock(new_fd[2]); window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (cctx->want_tty) { window >>= 1; packetmax >>= 1; } nc = channel_new("session", SSH_CHANNEL_OPENING, new_fd[0], new_fd[1], new_fd[2], window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); nc->ctl_chan = c->self; /* link session -> control channel */ c->remote_id = nc->self; /* link control -> session channel */ if (cctx->want_tty && escape_char != 0xffffffff) { channel_register_filter(nc->self, client_simple_escape_filter, NULL, client_filter_cleanup, client_new_escape_filter_ctx((int)escape_char)); } debug2("%s: channel_new: %d linked to control channel %d", __func__, nc->self, nc->ctl_chan); channel_send_open(nc->self); channel_register_open_confirm(nc->self, mux_session_confirm, cctx); c->mux_pause = 1; /* stop handling messages until open_confirm done */ channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); /* reply is deferred, sent by mux_session_confirm */ return 0; } static int process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) { debug2("%s: channel %d: alive check", __func__, c->self); /* prepare reply */ buffer_put_int(r, MUX_S_ALIVE); buffer_put_int(r, rid); buffer_put_int(r, (u_int)getpid()); return 0; } static int process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) { debug2("%s: channel %d: terminate request", __func__, c->self); if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Terminate shared connection to %s? ", host)) { debug2("%s: termination refused by user", __func__); buffer_put_int(r, MUX_S_PERMISSION_DENIED); buffer_put_int(r, rid); buffer_put_cstring(r, "Permission denied"); return 0; } } quit_pending = 1; buffer_put_int(r, MUX_S_OK); buffer_put_int(r, rid); /* XXX exit happens too soon - message never makes it to client */ return 0; } static char * format_forward(u_int ftype, struct Forward *fwd) { char *ret; switch (ftype) { case MUX_FWD_LOCAL: xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", (fwd->listen_path != NULL) ? fwd->listen_path : (fwd->listen_host == NULL) ? (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : fwd->listen_host, fwd->listen_port, (fwd->connect_path != NULL) ? fwd->connect_path : fwd->connect_host, fwd->connect_port); break; case MUX_FWD_DYNAMIC: xasprintf(&ret, "dynamic forward %.200s:%d -> *", (fwd->listen_host == NULL) ? (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : fwd->listen_host, fwd->listen_port); break; case MUX_FWD_REMOTE: xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", (fwd->listen_path != NULL) ? fwd->listen_path : (fwd->listen_host == NULL) ? "LOCALHOST" : fwd->listen_host, fwd->listen_port, (fwd->connect_path != NULL) ? fwd->connect_path : fwd->connect_host, fwd->connect_port); break; default: fatal("%s: unknown forward type %u", __func__, ftype); } return ret; } static int compare_host(const char *a, const char *b) { if (a == NULL && b == NULL) return 1; if (a == NULL || b == NULL) return 0; return strcmp(a, b) == 0; } static int compare_forward(struct Forward *a, struct Forward *b) { if (!compare_host(a->listen_host, b->listen_host)) return 0; if (!compare_host(a->listen_path, b->listen_path)) return 0; if (a->listen_port != b->listen_port) return 0; if (!compare_host(a->connect_host, b->connect_host)) return 0; if (!compare_host(a->connect_path, b->connect_path)) return 0; if (a->connect_port != b->connect_port) return 0; return 1; } static void mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) { struct mux_channel_confirm_ctx *fctx = ctxt; char *failmsg = NULL; struct Forward *rfwd; Channel *c; Buffer out; if ((c = channel_by_id(fctx->cid)) == NULL) { /* no channel for reply */ error("%s: unknown channel", __func__); return; } buffer_init(&out); if (fctx->fid >= options.num_remote_forwards || (options.remote_forwards[fctx->fid].connect_path == NULL && options.remote_forwards[fctx->fid].connect_host == NULL)) { xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid); goto fail; } rfwd = &options.remote_forwards[fctx->fid]; debug("%s: %s for: listen %d, connect %s:%d", __func__, type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : rfwd->connect_host, rfwd->connect_port); if (type == SSH2_MSG_REQUEST_SUCCESS) { if (rfwd->listen_port == 0) { rfwd->allocated_port = packet_get_int(); debug("Allocated port %u for mux remote forward" " to %s:%d", rfwd->allocated_port, rfwd->connect_host, rfwd->connect_port); buffer_put_int(&out, MUX_S_REMOTE_PORT); buffer_put_int(&out, fctx->rid); buffer_put_int(&out, rfwd->allocated_port); channel_update_permitted_opens(rfwd->handle, rfwd->allocated_port); } else { buffer_put_int(&out, MUX_S_OK); buffer_put_int(&out, fctx->rid); } goto out; } else { if (rfwd->listen_port == 0) channel_update_permitted_opens(rfwd->handle, -1); if (rfwd->listen_path != NULL) xasprintf(&failmsg, "remote port forwarding failed for " "listen path %s", rfwd->listen_path); else xasprintf(&failmsg, "remote port forwarding failed for " "listen port %d", rfwd->listen_port); debug2("%s: clearing registered forwarding for listen %d, " "connect %s:%d", __func__, rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : rfwd->connect_host, rfwd->connect_port); free(rfwd->listen_host); free(rfwd->listen_path); free(rfwd->connect_host); free(rfwd->connect_path); memset(rfwd, 0, sizeof(*rfwd)); } fail: error("%s: %s", __func__, failmsg); buffer_put_int(&out, MUX_S_FAILURE); buffer_put_int(&out, fctx->rid); buffer_put_cstring(&out, failmsg); free(failmsg); out: buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); buffer_free(&out); if (c->mux_pause <= 0) fatal("%s: mux_pause %d", __func__, c->mux_pause); c->mux_pause = 0; /* start processing messages again */ } static int process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) { struct Forward fwd; char *fwd_desc = NULL; char *listen_addr, *connect_addr; u_int ftype; u_int lport, cport; int i, ret = 0, freefwd = 1; memset(&fwd, 0, sizeof(fwd)); /* XXX - lport/cport check redundant */ if (buffer_get_int_ret(&ftype, m) != 0 || (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&lport, m) != 0 || (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&cport, m) != 0 || (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { error("%s: malformed message", __func__); ret = -1; goto out; } if (*listen_addr == '\0') { free(listen_addr); listen_addr = NULL; } if (*connect_addr == '\0') { free(connect_addr); connect_addr = NULL; } memset(&fwd, 0, sizeof(fwd)); fwd.listen_port = lport; if (fwd.listen_port == PORT_STREAMLOCAL) fwd.listen_path = listen_addr; else fwd.listen_host = listen_addr; fwd.connect_port = cport; if (fwd.connect_port == PORT_STREAMLOCAL) fwd.connect_path = connect_addr; else fwd.connect_host = connect_addr; debug2("%s: channel %d: request %s", __func__, c->self, (fwd_desc = format_forward(ftype, &fwd))); if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE && ftype != MUX_FWD_DYNAMIC) { logit("%s: invalid forwarding type %u", __func__, ftype); invalid: free(listen_addr); free(connect_addr); buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "Invalid forwarding request"); return 0; } if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) { logit("%s: streamlocal and dynamic forwards " "are mutually exclusive", __func__); goto invalid; } if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) { logit("%s: invalid listen port %u", __func__, fwd.listen_port); goto invalid; } if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { logit("%s: invalid connect port %u", __func__, fwd.connect_port); goto invalid; } if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { logit("%s: missing connect host", __func__); goto invalid; } /* Skip forwards that have already been requested */ switch (ftype) { case MUX_FWD_LOCAL: case MUX_FWD_DYNAMIC: for (i = 0; i < options.num_local_forwards; i++) { if (compare_forward(&fwd, options.local_forwards + i)) { exists: debug2("%s: found existing forwarding", __func__); buffer_put_int(r, MUX_S_OK); buffer_put_int(r, rid); goto out; } } break; case MUX_FWD_REMOTE: for (i = 0; i < options.num_remote_forwards; i++) { if (compare_forward(&fwd, options.remote_forwards + i)) { if (fwd.listen_port != 0) goto exists; debug2("%s: found allocated port", __func__); buffer_put_int(r, MUX_S_REMOTE_PORT); buffer_put_int(r, rid); buffer_put_int(r, options.remote_forwards[i].allocated_port); goto out; } } break; } if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Open %s on %s?", fwd_desc, host)) { debug2("%s: forwarding refused by user", __func__); buffer_put_int(r, MUX_S_PERMISSION_DENIED); buffer_put_int(r, rid); buffer_put_cstring(r, "Permission denied"); goto out; } } if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { if (!channel_setup_local_fwd_listener(&fwd, &options.fwd_opts)) { fail: logit("slave-requested %s failed", fwd_desc); buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "Port forwarding failed"); goto out; } add_local_forward(&options, &fwd); freefwd = 0; } else { struct mux_channel_confirm_ctx *fctx; fwd.handle = channel_request_remote_forwarding(&fwd); if (fwd.handle < 0) goto fail; add_remote_forward(&options, &fwd); fctx = xcalloc(1, sizeof(*fctx)); fctx->cid = c->self; fctx->rid = rid; fctx->fid = options.num_remote_forwards - 1; client_register_global_confirm(mux_confirm_remote_forward, fctx); freefwd = 0; c->mux_pause = 1; /* wait for mux_confirm_remote_forward */ /* delayed reply in mux_confirm_remote_forward */ goto out; } buffer_put_int(r, MUX_S_OK); buffer_put_int(r, rid); out: free(fwd_desc); if (freefwd) { free(fwd.listen_host); free(fwd.listen_path); free(fwd.connect_host); free(fwd.connect_path); } return ret; } static int process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) { struct Forward fwd, *found_fwd; char *fwd_desc = NULL; const char *error_reason = NULL; char *listen_addr = NULL, *connect_addr = NULL; u_int ftype; int i, ret = 0; u_int lport, cport; memset(&fwd, 0, sizeof(fwd)); if (buffer_get_int_ret(&ftype, m) != 0 || (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&lport, m) != 0 || (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&cport, m) != 0 || (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { error("%s: malformed message", __func__); ret = -1; goto out; } if (*listen_addr == '\0') { free(listen_addr); listen_addr = NULL; } if (*connect_addr == '\0') { free(connect_addr); connect_addr = NULL; } memset(&fwd, 0, sizeof(fwd)); fwd.listen_port = lport; if (fwd.listen_port == PORT_STREAMLOCAL) fwd.listen_path = listen_addr; else fwd.listen_host = listen_addr; fwd.connect_port = cport; if (fwd.connect_port == PORT_STREAMLOCAL) fwd.connect_path = connect_addr; else fwd.connect_host = connect_addr; debug2("%s: channel %d: request cancel %s", __func__, c->self, (fwd_desc = format_forward(ftype, &fwd))); /* make sure this has been requested */ found_fwd = NULL; switch (ftype) { case MUX_FWD_LOCAL: case MUX_FWD_DYNAMIC: for (i = 0; i < options.num_local_forwards; i++) { if (compare_forward(&fwd, options.local_forwards + i)) { found_fwd = options.local_forwards + i; break; } } break; case MUX_FWD_REMOTE: for (i = 0; i < options.num_remote_forwards; i++) { if (compare_forward(&fwd, options.remote_forwards + i)) { found_fwd = options.remote_forwards + i; break; } } break; } if (found_fwd == NULL) error_reason = "port not forwarded"; else if (ftype == MUX_FWD_REMOTE) { /* * This shouldn't fail unless we confused the host/port * between options.remote_forwards and permitted_opens. * However, for dynamic allocated listen ports we need * to use the actual listen port. */ if (channel_request_rforward_cancel(found_fwd) == -1) error_reason = "port not in permitted opens"; } else { /* local and dynamic forwards */ /* Ditto */ if (channel_cancel_lport_listener(&fwd, fwd.connect_port, &options.fwd_opts) == -1) error_reason = "port not found"; } if (error_reason == NULL) { buffer_put_int(r, MUX_S_OK); buffer_put_int(r, rid); free(found_fwd->listen_host); free(found_fwd->listen_path); free(found_fwd->connect_host); free(found_fwd->connect_path); found_fwd->listen_host = found_fwd->connect_host = NULL; found_fwd->listen_path = found_fwd->connect_path = NULL; found_fwd->listen_port = found_fwd->connect_port = 0; } else { buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, error_reason); } out: free(fwd_desc); free(listen_addr); free(connect_addr); return ret; } static int process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) { Channel *nc; char *reserved, *chost; u_int cport, i, j; int new_fd[2]; struct mux_stdio_confirm_ctx *cctx; chost = reserved = NULL; if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || (chost = buffer_get_string_ret(m, NULL)) == NULL || buffer_get_int_ret(&cport, m) != 0) { free(reserved); free(chost); error("%s: malformed message", __func__); return -1; } free(reserved); debug2("%s: channel %d: request stdio fwd to %s:%u", __func__, c->self, chost, cport); /* Gather fds from client */ for(i = 0; i < 2; i++) { if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) { error("%s: failed to receive fd %d from slave", __func__, i); for (j = 0; j < i; j++) close(new_fd[j]); free(chost); /* prepare reply */ buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "did not receive file descriptors"); return -1; } } debug3("%s: got fds stdin %d, stdout %d", __func__, new_fd[0], new_fd[1]); /* XXX support multiple child sessions in future */ if (c->remote_id != -1) { debug2("%s: session already open", __func__); /* prepare reply */ buffer_put_int(r, MUX_S_FAILURE); buffer_put_int(r, rid); buffer_put_cstring(r, "Multiple sessions not supported"); cleanup: close(new_fd[0]); close(new_fd[1]); free(chost); return 0; } if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Allow forward to %s:%u? ", chost, cport)) { debug2("%s: stdio fwd refused by user", __func__); /* prepare reply */ buffer_put_int(r, MUX_S_PERMISSION_DENIED); buffer_put_int(r, rid); buffer_put_cstring(r, "Permission denied"); goto cleanup; } } /* enable nonblocking unless tty */ if (!isatty(new_fd[0])) set_nonblock(new_fd[0]); if (!isatty(new_fd[1])) set_nonblock(new_fd[1]); nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); nc->ctl_chan = c->self; /* link session -> control channel */ c->remote_id = nc->self; /* link control -> session channel */ debug2("%s: channel_new: %d linked to control channel %d", __func__, nc->self, nc->ctl_chan); channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); cctx = xcalloc(1, sizeof(*cctx)); cctx->rid = rid; channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx); c->mux_pause = 1; /* stop handling messages until open_confirm done */ /* reply is deferred, sent by mux_session_confirm */ return 0; } /* Callback on open confirmation in mux master for a mux stdio fwd session. */ static void mux_stdio_confirm(int id, int success, void *arg) { struct mux_stdio_confirm_ctx *cctx = arg; Channel *c, *cc; Buffer reply; if (cctx == NULL) fatal("%s: cctx == NULL", __func__); if ((c = channel_by_id(id)) == NULL) fatal("%s: no channel for id %d", __func__, id); if ((cc = channel_by_id(c->ctl_chan)) == NULL) fatal("%s: channel %d lacks control channel %d", __func__, id, c->ctl_chan); if (!success) { debug3("%s: sending failure reply", __func__); /* prepare reply */ buffer_init(&reply); buffer_put_int(&reply, MUX_S_FAILURE); buffer_put_int(&reply, cctx->rid); buffer_put_cstring(&reply, "Session open refused by peer"); goto done; } debug3("%s: sending success reply", __func__); /* prepare reply */ buffer_init(&reply); buffer_put_int(&reply, MUX_S_SESSION_OPENED); buffer_put_int(&reply, cctx->rid); buffer_put_int(&reply, c->self); done: /* Send reply */ buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); buffer_free(&reply); if (cc->mux_pause <= 0) fatal("%s: mux_pause %d", __func__, cc->mux_pause); cc->mux_pause = 0; /* start processing messages again */ c->open_confirm_ctx = NULL; free(cctx); } static int process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) { debug("%s: channel %d: stop listening", __func__, c->self); if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { if (!ask_permission("Disable further multiplexing on shared " "connection to %s? ", host)) { debug2("%s: stop listen refused by user", __func__); buffer_put_int(r, MUX_S_PERMISSION_DENIED); buffer_put_int(r, rid); buffer_put_cstring(r, "Permission denied"); return 0; } } if (mux_listener_channel != NULL) { channel_free(mux_listener_channel); client_stop_mux(); free(options.control_path); options.control_path = NULL; mux_listener_channel = NULL; muxserver_sock = -1; } /* prepare reply */ buffer_put_int(r, MUX_S_OK); buffer_put_int(r, rid); return 0; } /* Channel callbacks fired on read/write from mux slave fd */ static int mux_master_read_cb(Channel *c) { struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; Buffer in, out; const u_char *ptr; u_int type, rid, have, i; int ret = -1; /* Setup ctx and */ if (c->mux_ctx == NULL) { state = xcalloc(1, sizeof(*state)); c->mux_ctx = state; channel_register_cleanup(c->self, mux_master_control_cleanup_cb, 0); /* Send hello */ buffer_init(&out); buffer_put_int(&out, MUX_MSG_HELLO); buffer_put_int(&out, SSHMUX_VER); /* no extensions */ buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); buffer_free(&out); debug3("%s: channel %d: hello sent", __func__, c->self); return 0; } buffer_init(&in); buffer_init(&out); /* Channel code ensures that we receive whole packets */ if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { malf: error("%s: malformed message", __func__); goto out; } buffer_append(&in, ptr, have); if (buffer_get_int_ret(&type, &in) != 0) goto malf; debug3("%s: channel %d packet type 0x%08x len %u", __func__, c->self, type, buffer_len(&in)); if (type == MUX_MSG_HELLO) rid = 0; else { if (!state->hello_rcvd) { error("%s: expected MUX_MSG_HELLO(0x%08x), " "received 0x%08x", __func__, MUX_MSG_HELLO, type); goto out; } if (buffer_get_int_ret(&rid, &in) != 0) goto malf; } for (i = 0; mux_master_handlers[i].handler != NULL; i++) { if (type == mux_master_handlers[i].type) { ret = mux_master_handlers[i].handler(rid, c, &in, &out); break; } } if (mux_master_handlers[i].handler == NULL) { error("%s: unsupported mux message 0x%08x", __func__, type); buffer_put_int(&out, MUX_S_FAILURE); buffer_put_int(&out, rid); buffer_put_cstring(&out, "unsupported request"); ret = 0; } /* Enqueue reply packet */ if (buffer_len(&out) != 0) { buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); } out: buffer_free(&in); buffer_free(&out); return ret; } void mux_exit_message(Channel *c, int exitval) { Buffer m; Channel *mux_chan; debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, exitval); if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) fatal("%s: channel %d missing mux channel %d", __func__, c->self, c->ctl_chan); /* Append exit message packet to control socket output queue */ buffer_init(&m); buffer_put_int(&m, MUX_S_EXIT_MESSAGE); buffer_put_int(&m, c->self); buffer_put_int(&m, exitval); buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); buffer_free(&m); } void mux_tty_alloc_failed(Channel *c) { Buffer m; Channel *mux_chan; debug3("%s: channel %d: TTY alloc failed", __func__, c->self); if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) fatal("%s: channel %d missing mux channel %d", __func__, c->self, c->ctl_chan); /* Append exit message packet to control socket output queue */ buffer_init(&m); buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); buffer_put_int(&m, c->self); buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); buffer_free(&m); } /* Prepare a mux master to listen on a Unix domain socket. */ void muxserver_listen(void) { mode_t old_umask; char *orig_control_path = options.control_path; char rbuf[16+1]; u_int i, r; int oerrno; if (options.control_path == NULL || options.control_master == SSHCTL_MASTER_NO) return; debug("setting up multiplex master socket"); /* * Use a temporary path before listen so we can pseudo-atomically * establish the listening socket in its final location to avoid * other processes racing in between bind() and listen() and hitting * an unready socket. */ for (i = 0; i < sizeof(rbuf) - 1; i++) { r = arc4random_uniform(26+26+10); rbuf[i] = (r < 26) ? 'a' + r : (r < 26*2) ? 'A' + r - 26 : '0' + r - 26 - 26; } rbuf[sizeof(rbuf) - 1] = '\0'; options.control_path = NULL; xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); debug3("%s: temporary control path %s", __func__, options.control_path); old_umask = umask(0177); muxserver_sock = unix_listener(options.control_path, 64, 0); oerrno = errno; umask(old_umask); if (muxserver_sock < 0) { if (oerrno == EINVAL || oerrno == EADDRINUSE) { error("ControlSocket %s already exists, " "disabling multiplexing", options.control_path); disable_mux_master: if (muxserver_sock != -1) { close(muxserver_sock); muxserver_sock = -1; } free(orig_control_path); free(options.control_path); options.control_path = NULL; options.control_master = SSHCTL_MASTER_NO; return; } else { /* unix_listener() logs the error */ cleanup_exit(255); } } /* Now atomically "move" the mux socket into position */ if (link(options.control_path, orig_control_path) != 0) { if (errno != EEXIST) { fatal("%s: link mux listener %s => %s: %s", __func__, options.control_path, orig_control_path, strerror(errno)); } error("ControlSocket %s already exists, disabling multiplexing", orig_control_path); unlink(options.control_path); goto disable_mux_master; } unlink(options.control_path); free(options.control_path); options.control_path = orig_control_path; set_nonblock(muxserver_sock); mux_listener_channel = channel_new("mux listener", SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, options.control_path, 1); mux_listener_channel->mux_rcb = mux_master_read_cb; debug3("%s: mux listener channel %d fd %d", __func__, mux_listener_channel->self, mux_listener_channel->sock); } /* Callback on open confirmation in mux master for a mux client session. */ static void mux_session_confirm(int id, int success, void *arg) { struct mux_session_confirm_ctx *cctx = arg; const char *display; Channel *c, *cc; int i; Buffer reply; if (cctx == NULL) fatal("%s: cctx == NULL", __func__); if ((c = channel_by_id(id)) == NULL) fatal("%s: no channel for id %d", __func__, id); if ((cc = channel_by_id(c->ctl_chan)) == NULL) fatal("%s: channel %d lacks control channel %d", __func__, id, c->ctl_chan); if (!success) { debug3("%s: sending failure reply", __func__); /* prepare reply */ buffer_init(&reply); buffer_put_int(&reply, MUX_S_FAILURE); buffer_put_int(&reply, cctx->rid); buffer_put_cstring(&reply, "Session open refused by peer"); goto done; } display = getenv("DISPLAY"); if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { char *proto, *data; /* Get reasonable local authentication information. */ if (client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, options.forward_x11_timeout, &proto, &data) == 0) { /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication " "spoofing."); x11_request_forwarding_with_spoofing(id, display, proto, data, 1); /* XXX exit_on_forward_failure */ client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); } } if (cctx->want_agent_fwd && options.forward_agent) { debug("Requesting authentication agent forwarding."); channel_request_start(id, "auth-agent-req@openssh.com", 0); packet_send(); } client_session2_setup(id, cctx->want_tty, cctx->want_subsys, cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); debug3("%s: sending success reply", __func__); /* prepare reply */ buffer_init(&reply); buffer_put_int(&reply, MUX_S_SESSION_OPENED); buffer_put_int(&reply, cctx->rid); buffer_put_int(&reply, c->self); done: /* Send reply */ buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); buffer_free(&reply); if (cc->mux_pause <= 0) fatal("%s: mux_pause %d", __func__, cc->mux_pause); cc->mux_pause = 0; /* start processing messages again */ c->open_confirm_ctx = NULL; buffer_free(&cctx->cmd); free(cctx->term); if (cctx->env != NULL) { for (i = 0; cctx->env[i] != NULL; i++) free(cctx->env[i]); free(cctx->env); } free(cctx); } /* ** Multiplexing client support */ /* Exit signal handler */ static void control_client_sighandler(int signo) { muxclient_terminate = signo; } /* * Relay signal handler - used to pass some signals from mux client to * mux master. */ static void control_client_sigrelay(int signo) { int save_errno = errno; if (muxserver_pid > 1) kill(muxserver_pid, signo); errno = save_errno; } static int mux_client_read(int fd, Buffer *b, u_int need) { u_int have; ssize_t len; u_char *p; struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; p = buffer_append_space(b, need); for (have = 0; have < need; ) { if (muxclient_terminate) { errno = EINTR; return -1; } len = read(fd, p + have, need - have); if (len < 0) { switch (errno) { #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: (void)poll(&pfd, 1, -1); /* FALLTHROUGH */ case EINTR: continue; default: return -1; } } if (len == 0) { errno = EPIPE; return -1; } have += (u_int)len; } return 0; } static int mux_client_write_packet(int fd, Buffer *m) { Buffer queue; u_int have, need; int oerrno, len; u_char *ptr; struct pollfd pfd; pfd.fd = fd; pfd.events = POLLOUT; buffer_init(&queue); buffer_put_string(&queue, buffer_ptr(m), buffer_len(m)); need = buffer_len(&queue); ptr = buffer_ptr(&queue); for (have = 0; have < need; ) { if (muxclient_terminate) { buffer_free(&queue); errno = EINTR; return -1; } len = write(fd, ptr + have, need - have); if (len < 0) { switch (errno) { #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: (void)poll(&pfd, 1, -1); /* FALLTHROUGH */ case EINTR: continue; default: oerrno = errno; buffer_free(&queue); errno = oerrno; return -1; } } if (len == 0) { buffer_free(&queue); errno = EPIPE; return -1; } have += (u_int)len; } buffer_free(&queue); return 0; } static int mux_client_read_packet(int fd, Buffer *m) { Buffer queue; u_int need, have; const u_char *ptr; int oerrno; buffer_init(&queue); if (mux_client_read(fd, &queue, 4) != 0) { if ((oerrno = errno) == EPIPE) debug3("%s: read header failed: %s", __func__, strerror(errno)); buffer_free(&queue); errno = oerrno; return -1; } need = get_u32(buffer_ptr(&queue)); if (mux_client_read(fd, &queue, need) != 0) { oerrno = errno; debug3("%s: read body failed: %s", __func__, strerror(errno)); buffer_free(&queue); errno = oerrno; return -1; } ptr = buffer_get_string_ptr(&queue, &have); buffer_append(m, ptr, have); buffer_free(&queue); return 0; } static int mux_client_hello_exchange(int fd) { Buffer m; u_int type, ver; buffer_init(&m); buffer_put_int(&m, MUX_MSG_HELLO); buffer_put_int(&m, SSHMUX_VER); /* no extensions */ if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); /* Read their HELLO */ if (mux_client_read_packet(fd, &m) != 0) { buffer_free(&m); return -1; } type = buffer_get_int(&m); if (type != MUX_MSG_HELLO) fatal("%s: expected HELLO (%u) received %u", __func__, MUX_MSG_HELLO, type); ver = buffer_get_int(&m); if (ver != SSHMUX_VER) fatal("Unsupported multiplexing protocol version %d " "(expected %d)", ver, SSHMUX_VER); debug2("%s: master version %u", __func__, ver); /* No extensions are presently defined */ while (buffer_len(&m) > 0) { char *name = buffer_get_string(&m, NULL); char *value = buffer_get_string(&m, NULL); debug2("Unrecognised master extension \"%s\"", name); free(name); free(value); } buffer_free(&m); return 0; } static u_int mux_client_request_alive(int fd) { Buffer m; char *e; u_int pid, type, rid; debug3("%s: entering", __func__); buffer_init(&m); buffer_put_int(&m, MUX_C_ALIVE_CHECK); buffer_put_int(&m, muxclient_request_id); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); /* Read their reply */ if (mux_client_read_packet(fd, &m) != 0) { buffer_free(&m); return 0; } type = buffer_get_int(&m); if (type != MUX_S_ALIVE) { e = buffer_get_string(&m, NULL); fatal("%s: master returned error: %s", __func__, e); } if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); pid = buffer_get_int(&m); buffer_free(&m); debug3("%s: done pid = %u", __func__, pid); muxclient_request_id++; return pid; } static void mux_client_request_terminate(int fd) { Buffer m; char *e; u_int type, rid; debug3("%s: entering", __func__); buffer_init(&m); buffer_put_int(&m, MUX_C_TERMINATE); buffer_put_int(&m, muxclient_request_id); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); /* Read their reply */ if (mux_client_read_packet(fd, &m) != 0) { /* Remote end exited already */ if (errno == EPIPE) { buffer_free(&m); return; } fatal("%s: read from master failed: %s", __func__, strerror(errno)); } type = buffer_get_int(&m); if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); switch (type) { case MUX_S_OK: break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); fatal("Master refused termination request: %s", e); case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); fatal("%s: termination request failed: %s", __func__, e); default: fatal("%s: unexpected response from master 0x%08x", __func__, type); } buffer_free(&m); muxclient_request_id++; } static int mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd) { Buffer m; char *e, *fwd_desc; u_int type, rid; fwd_desc = format_forward(ftype, fwd); debug("Requesting %s %s", cancel_flag ? "cancellation of" : "forwarding of", fwd_desc); free(fwd_desc); buffer_init(&m); buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); buffer_put_int(&m, muxclient_request_id); buffer_put_int(&m, ftype); if (fwd->listen_path != NULL) { buffer_put_cstring(&m, fwd->listen_path); } else { buffer_put_cstring(&m, fwd->listen_host == NULL ? "" : (*fwd->listen_host == '\0' ? "*" : fwd->listen_host)); } buffer_put_int(&m, fwd->listen_port); if (fwd->connect_path != NULL) { buffer_put_cstring(&m, fwd->connect_path); } else { buffer_put_cstring(&m, fwd->connect_host == NULL ? "" : fwd->connect_host); } buffer_put_int(&m, fwd->connect_port); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); /* Read their reply */ if (mux_client_read_packet(fd, &m) != 0) { buffer_free(&m); return -1; } type = buffer_get_int(&m); if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); switch (type) { case MUX_S_OK: break; case MUX_S_REMOTE_PORT: if (cancel_flag) fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__); fwd->allocated_port = buffer_get_int(&m); verbose("Allocated port %u for remote forward to %s:%d", fwd->allocated_port, fwd->connect_host ? fwd->connect_host : "", fwd->connect_port); if (muxclient_command == SSHMUX_COMMAND_FORWARD) fprintf(stdout, "%i\n", fwd->allocated_port); break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); buffer_free(&m); error("Master refused forwarding request: %s", e); return -1; case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); error("%s: forwarding request failed: %s", __func__, e); return -1; default: fatal("%s: unexpected response from master 0x%08x", __func__, type); } buffer_free(&m); muxclient_request_id++; return 0; } static int mux_client_forwards(int fd, int cancel_flag) { int i, ret = 0; debug3("%s: %s forwardings: %d local, %d remote", __func__, cancel_flag ? "cancel" : "request", options.num_local_forwards, options.num_remote_forwards); /* XXX ExitOnForwardingFailure */ for (i = 0; i < options.num_local_forwards; i++) { if (mux_client_forward(fd, cancel_flag, options.local_forwards[i].connect_port == 0 ? MUX_FWD_DYNAMIC : MUX_FWD_LOCAL, options.local_forwards + i) != 0) ret = -1; } for (i = 0; i < options.num_remote_forwards; i++) { if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE, options.remote_forwards + i) != 0) ret = -1; } return ret; } static int mux_client_request_session(int fd) { Buffer m; char *e, *term; u_int i, rid, sid, esid, exitval, type, exitval_seen; extern char **environ; int devnull, rawmode; debug3("%s: entering", __func__); if ((muxserver_pid = mux_client_request_alive(fd)) == 0) { error("%s: master alive request failed", __func__); return -1; } signal(SIGPIPE, SIG_IGN); if (stdin_null_flag) { if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1) fatal("open(/dev/null): %s", strerror(errno)); if (dup2(devnull, STDIN_FILENO) == -1) fatal("dup2: %s", strerror(errno)); if (devnull > STDERR_FILENO) close(devnull); } term = getenv("TERM"); buffer_init(&m); buffer_put_int(&m, MUX_C_NEW_SESSION); buffer_put_int(&m, muxclient_request_id); buffer_put_cstring(&m, ""); /* reserved */ buffer_put_int(&m, tty_flag); buffer_put_int(&m, options.forward_x11); buffer_put_int(&m, options.forward_agent); buffer_put_int(&m, subsystem_flag); buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ? 0xffffffff : (u_int)options.escape_char); buffer_put_cstring(&m, term == NULL ? "" : term); buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command)); if (options.num_send_env > 0 && environ != NULL) { /* Pass environment */ for (i = 0; environ[i] != NULL; i++) { if (env_permitted(environ[i])) { buffer_put_cstring(&m, environ[i]); } } } if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); /* Send the stdio file descriptors */ if (mm_send_fd(fd, STDIN_FILENO) == -1 || mm_send_fd(fd, STDOUT_FILENO) == -1 || mm_send_fd(fd, STDERR_FILENO) == -1) fatal("%s: send fds failed", __func__); debug3("%s: session request sent", __func__); /* Read their reply */ buffer_clear(&m); if (mux_client_read_packet(fd, &m) != 0) { error("%s: read from master failed: %s", __func__, strerror(errno)); buffer_free(&m); return -1; } type = buffer_get_int(&m); if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); switch (type) { case MUX_S_SESSION_OPENED: sid = buffer_get_int(&m); debug("%s: master session id: %u", __func__, sid); break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); buffer_free(&m); error("Master refused session request: %s", e); return -1; case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); error("%s: session request failed: %s", __func__, e); return -1; default: buffer_free(&m); error("%s: unexpected response from master 0x%08x", __func__, type); return -1; } muxclient_request_id++; if (pledge("stdio proc tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); platform_pledge_mux(); signal(SIGHUP, control_client_sighandler); signal(SIGINT, control_client_sighandler); signal(SIGTERM, control_client_sighandler); signal(SIGWINCH, control_client_sigrelay); rawmode = tty_flag; if (tty_flag) enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); /* * Stick around until the controlee closes the client_fd. * Before it does, it is expected to write an exit message. * This process must read the value and wait for the closure of * the client_fd; if this one closes early, the multiplex master will * terminate early too (possibly losing data). */ for (exitval = 255, exitval_seen = 0;;) { buffer_clear(&m); if (mux_client_read_packet(fd, &m) != 0) break; type = buffer_get_int(&m); switch (type) { case MUX_S_TTY_ALLOC_FAIL: if ((esid = buffer_get_int(&m)) != sid) fatal("%s: tty alloc fail on unknown session: " "my id %u theirs %u", __func__, sid, esid); leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); rawmode = 0; continue; case MUX_S_EXIT_MESSAGE: if ((esid = buffer_get_int(&m)) != sid) fatal("%s: exit on unknown session: " "my id %u theirs %u", __func__, sid, esid); if (exitval_seen) fatal("%s: exitval sent twice", __func__); exitval = buffer_get_int(&m); exitval_seen = 1; continue; default: e = buffer_get_string(&m, NULL); fatal("%s: master returned error: %s", __func__, e); } } close(fd); if (rawmode) leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); if (muxclient_terminate) { debug2("Exiting on signal %d", muxclient_terminate); exitval = 255; } else if (!exitval_seen) { debug2("Control master terminated unexpectedly"); exitval = 255; } else debug2("Received exit status from master %d", exitval); if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) fprintf(stderr, "Shared connection to %s closed.\r\n", host); exit(exitval); } static int mux_client_request_stdio_fwd(int fd) { Buffer m; char *e; u_int type, rid, sid; int devnull; debug3("%s: entering", __func__); if ((muxserver_pid = mux_client_request_alive(fd)) == 0) { error("%s: master alive request failed", __func__); return -1; } signal(SIGPIPE, SIG_IGN); if (stdin_null_flag) { if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1) fatal("open(/dev/null): %s", strerror(errno)); if (dup2(devnull, STDIN_FILENO) == -1) fatal("dup2: %s", strerror(errno)); if (devnull > STDERR_FILENO) close(devnull); } buffer_init(&m); buffer_put_int(&m, MUX_C_NEW_STDIO_FWD); buffer_put_int(&m, muxclient_request_id); buffer_put_cstring(&m, ""); /* reserved */ buffer_put_cstring(&m, stdio_forward_host); buffer_put_int(&m, stdio_forward_port); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); /* Send the stdio file descriptors */ if (mm_send_fd(fd, STDIN_FILENO) == -1 || mm_send_fd(fd, STDOUT_FILENO) == -1) fatal("%s: send fds failed", __func__); if (pledge("stdio proc tty", NULL) == -1) fatal("%s pledge(): %s", __func__, strerror(errno)); platform_pledge_mux(); debug3("%s: stdio forward request sent", __func__); /* Read their reply */ buffer_clear(&m); if (mux_client_read_packet(fd, &m) != 0) { error("%s: read from master failed: %s", __func__, strerror(errno)); buffer_free(&m); return -1; } type = buffer_get_int(&m); if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); switch (type) { case MUX_S_SESSION_OPENED: sid = buffer_get_int(&m); debug("%s: master session id: %u", __func__, sid); break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); buffer_free(&m); fatal("Master refused stdio forwarding request: %s", e); case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); fatal("Stdio forwarding request failed: %s", e); default: buffer_free(&m); error("%s: unexpected response from master 0x%08x", __func__, type); return -1; } muxclient_request_id++; signal(SIGHUP, control_client_sighandler); signal(SIGINT, control_client_sighandler); signal(SIGTERM, control_client_sighandler); signal(SIGWINCH, control_client_sigrelay); /* * Stick around until the controlee closes the client_fd. */ buffer_clear(&m); if (mux_client_read_packet(fd, &m) != 0) { if (errno == EPIPE || (errno == EINTR && muxclient_terminate != 0)) return 0; fatal("%s: mux_client_read_packet: %s", __func__, strerror(errno)); } fatal("%s: master returned unexpected message %u", __func__, type); } static void mux_client_request_stop_listening(int fd) { Buffer m; char *e; u_int type, rid; debug3("%s: entering", __func__); buffer_init(&m); buffer_put_int(&m, MUX_C_STOP_LISTENING); buffer_put_int(&m, muxclient_request_id); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); buffer_clear(&m); /* Read their reply */ if (mux_client_read_packet(fd, &m) != 0) fatal("%s: read from master failed: %s", __func__, strerror(errno)); type = buffer_get_int(&m); if ((rid = buffer_get_int(&m)) != muxclient_request_id) fatal("%s: out of sequence reply: my id %u theirs %u", __func__, muxclient_request_id, rid); switch (type) { case MUX_S_OK: break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); fatal("Master refused stop listening request: %s", e); case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); fatal("%s: stop listening request failed: %s", __func__, e); default: fatal("%s: unexpected response from master 0x%08x", __func__, type); } buffer_free(&m); muxclient_request_id++; } /* Multiplex client main loop. */ void muxclient(const char *path) { struct sockaddr_un addr; socklen_t sun_len; int sock; u_int pid; if (muxclient_command == 0) { if (stdio_forward_host != NULL) muxclient_command = SSHMUX_COMMAND_STDIO_FWD; else muxclient_command = SSHMUX_COMMAND_OPEN; } switch (options.control_master) { case SSHCTL_MASTER_AUTO: case SSHCTL_MASTER_AUTO_ASK: debug("auto-mux: Trying existing master"); /* FALLTHROUGH */ case SSHCTL_MASTER_NO: break; default: return; } memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; sun_len = offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1; if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) fatal("ControlPath too long"); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) fatal("%s socket(): %s", __func__, strerror(errno)); if (connect(sock, (struct sockaddr *)&addr, sun_len) == -1) { switch (muxclient_command) { case SSHMUX_COMMAND_OPEN: case SSHMUX_COMMAND_STDIO_FWD: break; default: fatal("Control socket connect(%.100s): %s", path, strerror(errno)); } if (errno == ECONNREFUSED && options.control_master != SSHCTL_MASTER_NO) { debug("Stale control socket %.100s, unlinking", path); unlink(path); } else if (errno == ENOENT) { debug("Control socket \"%.100s\" does not exist", path); } else { error("Control socket connect(%.100s): %s", path, strerror(errno)); } close(sock); return; } set_nonblock(sock); if (mux_client_hello_exchange(sock) != 0) { error("%s: master hello exchange failed", __func__); close(sock); return; } switch (muxclient_command) { case SSHMUX_COMMAND_ALIVE_CHECK: if ((pid = mux_client_request_alive(sock)) == 0) fatal("%s: master alive check failed", __func__); fprintf(stderr, "Master running (pid=%u)\r\n", pid); exit(0); case SSHMUX_COMMAND_TERMINATE: mux_client_request_terminate(sock); fprintf(stderr, "Exit request sent.\r\n"); exit(0); case SSHMUX_COMMAND_FORWARD: if (mux_client_forwards(sock, 0) != 0) fatal("%s: master forward request failed", __func__); exit(0); case SSHMUX_COMMAND_OPEN: if (mux_client_forwards(sock, 0) != 0) { error("%s: master forward request failed", __func__); return; } mux_client_request_session(sock); return; case SSHMUX_COMMAND_STDIO_FWD: mux_client_request_stdio_fwd(sock); exit(0); case SSHMUX_COMMAND_STOP: mux_client_request_stop_listening(sock); fprintf(stderr, "Stop listening request sent.\r\n"); exit(0); case SSHMUX_COMMAND_CANCEL_FWD: if (mux_client_forwards(sock, 1) != 0) error("%s: master cancel forward request failed", __func__); exit(0); default: fatal("unrecognised muxclient_command %d", muxclient_command); } } openssh-7.2p2/myproposal.h010064400017500001750000000121001267006270000140220ustar00djmdjm/* $OpenBSD: myproposal.h,v 1.50 2016/02/09 05:30:04 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 /* conditional algorithm support */ #ifdef OPENSSL_HAS_ECC #ifdef OPENSSL_HAS_NISTP521 # define KEX_ECDH_METHODS \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ "ecdh-sha2-nistp521," # define HOSTKEY_ECDSA_CERT_METHODS \ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ "ecdsa-sha2-nistp521-cert-v01@openssh.com," # define HOSTKEY_ECDSA_METHODS \ "ecdsa-sha2-nistp256," \ "ecdsa-sha2-nistp384," \ "ecdsa-sha2-nistp521," #else # define KEX_ECDH_METHODS \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," # define HOSTKEY_ECDSA_CERT_METHODS \ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ "ecdsa-sha2-nistp384-cert-v01@openssh.com," # define HOSTKEY_ECDSA_METHODS \ "ecdsa-sha2-nistp256," \ "ecdsa-sha2-nistp384," #endif #else # define KEX_ECDH_METHODS # define HOSTKEY_ECDSA_CERT_METHODS # define HOSTKEY_ECDSA_METHODS #endif #ifdef OPENSSL_HAVE_EVPGCM # define AESGCM_CIPHER_MODES \ ",aes128-gcm@openssh.com,aes256-gcm@openssh.com" #else # define AESGCM_CIPHER_MODES #endif #ifdef HAVE_EVP_SHA256 # define KEX_SHA256_METHODS \ "diffie-hellman-group-exchange-sha256," #define SHA2_HMAC_MODES \ "hmac-sha2-256," \ "hmac-sha2-512," #else # define KEX_SHA256_METHODS # define SHA2_HMAC_MODES #endif #ifdef WITH_OPENSSL # ifdef HAVE_EVP_SHA256 # define KEX_CURVE25519_METHODS "curve25519-sha256@libssh.org," # else # define KEX_CURVE25519_METHODS "" # endif #define KEX_COMMON_KEX \ KEX_CURVE25519_METHODS \ KEX_ECDH_METHODS \ KEX_SHA256_METHODS #define KEX_SERVER_KEX KEX_COMMON_KEX \ "diffie-hellman-group14-sha1" \ #define KEX_CLIENT_KEX KEX_COMMON_KEX \ "diffie-hellman-group-exchange-sha1," \ "diffie-hellman-group14-sha1" #define KEX_DEFAULT_PK_ALG \ HOSTKEY_ECDSA_CERT_METHODS \ "ssh-ed25519-cert-v01@openssh.com," \ "ssh-rsa-cert-v01@openssh.com," \ HOSTKEY_ECDSA_METHODS \ "ssh-ed25519," \ "rsa-sha2-512," \ "rsa-sha2-256," \ "ssh-rsa" /* the actual algorithms */ #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr" \ AESGCM_CIPHER_MODES #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ "aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc" #define KEX_SERVER_MAC \ "umac-64-etm@openssh.com," \ "umac-128-etm@openssh.com," \ "hmac-sha2-256-etm@openssh.com," \ "hmac-sha2-512-etm@openssh.com," \ "hmac-sha1-etm@openssh.com," \ "umac-64@openssh.com," \ "umac-128@openssh.com," \ "hmac-sha2-256," \ "hmac-sha2-512," \ "hmac-sha1" #define KEX_CLIENT_MAC KEX_SERVER_MAC #else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ "curve25519-sha256@libssh.org" #define KEX_DEFAULT_PK_ALG \ "ssh-ed25519-cert-v01@openssh.com," \ "ssh-ed25519" #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_SERVER_MAC \ "umac-64-etm@openssh.com," \ "umac-128-etm@openssh.com," \ "hmac-sha2-256-etm@openssh.com," \ "hmac-sha2-512-etm@openssh.com," \ "hmac-sha1-etm@openssh.com," \ "umac-64@openssh.com," \ "umac-128@openssh.com," \ "hmac-sha2-256," \ "hmac-sha2-512," \ "hmac-sha1" #define KEX_CLIENT_KEX KEX_SERVER_KEX #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT #define KEX_CLIENT_MAC KEX_SERVER_MAC #endif /* WITH_OPENSSL */ #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" #define KEX_DEFAULT_LANG "" #define KEX_CLIENT \ KEX_CLIENT_KEX, \ KEX_DEFAULT_PK_ALG, \ KEX_CLIENT_ENCRYPT, \ KEX_CLIENT_ENCRYPT, \ KEX_CLIENT_MAC, \ KEX_CLIENT_MAC, \ KEX_DEFAULT_COMP, \ KEX_DEFAULT_COMP, \ KEX_DEFAULT_LANG, \ KEX_DEFAULT_LANG #define KEX_SERVER \ KEX_SERVER_KEX, \ KEX_DEFAULT_PK_ALG, \ KEX_SERVER_ENCRYPT, \ KEX_SERVER_ENCRYPT, \ KEX_SERVER_MAC, \ KEX_SERVER_MAC, \ KEX_DEFAULT_COMP, \ KEX_DEFAULT_COMP, \ KEX_DEFAULT_LANG, \ KEX_DEFAULT_LANG openssh-7.2p2/nchan.c010064400017500001750000000315231267006270000127110ustar00djmdjm/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm 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 #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "ssh1.h" #include "ssh2.h" #include "buffer.h" #include "packet.h" #include "channels.h" #include "compat.h" #include "log.h" /* * SSH Protocol 1.5 aka New Channel Protocol * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. * Written by Markus Friedl in October 1999 * * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the * tear down of channels: * * 1.3: strict request-ack-protocol: * CLOSE -> * <- CLOSE_CONFIRM * * 1.5: uses variations of: * IEOF -> * <- OCLOSE * <- IEOF * OCLOSE -> * i.e. both sides have to close the channel * * 2.0: the EOF messages are optional * * See the debugging output from 'ssh -v' and 'sshd -d' of * ssh-1.2.27 as an example. * */ /* functions manipulating channel states */ /* * EVENTS update channel input/output states execute ACTIONS */ /* * ACTIONS: should never update the channel states */ static void chan_send_ieof1(Channel *); static void chan_send_oclose1(Channel *); static void chan_send_close2(Channel *); static void chan_send_eof2(Channel *); static void chan_send_eow2(Channel *); /* helper */ static void chan_shutdown_write(Channel *); static void chan_shutdown_read(Channel *); static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; static void chan_set_istate(Channel *c, u_int next) { if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED) fatal("chan_set_istate: bad state %d -> %d", c->istate, next); debug2("channel %d: input %s -> %s", c->self, istates[c->istate], istates[next]); c->istate = next; } static void chan_set_ostate(Channel *c, u_int next) { if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED) fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next); debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate], ostates[next]); c->ostate = next; } /* * SSH1 specific implementation of event functions */ static void chan_rcvd_oclose1(Channel *c) { debug2("channel %d: rcvd oclose", c->self); switch (c->istate) { case CHAN_INPUT_WAIT_OCLOSE: chan_set_istate(c, CHAN_INPUT_CLOSED); break; case CHAN_INPUT_OPEN: chan_shutdown_read(c); chan_send_ieof1(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; case CHAN_INPUT_WAIT_DRAIN: /* both local read_failed and remote write_failed */ chan_send_ieof1(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; default: error("channel %d: protocol error: rcvd_oclose for istate %d", c->self, c->istate); return; } } void chan_read_failed(Channel *c) { debug2("channel %d: read failed", c->self); switch (c->istate) { case CHAN_INPUT_OPEN: chan_shutdown_read(c); chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); break; default: error("channel %d: chan_read_failed for istate %d", c->self, c->istate); break; } } void chan_ibuf_empty(Channel *c) { debug2("channel %d: ibuf empty", c->self); if (buffer_len(&c->input)) { error("channel %d: chan_ibuf_empty for non empty buffer", c->self); return; } switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: if (compat20) { if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); } else { chan_send_ieof1(c); chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); } break; default: error("channel %d: chan_ibuf_empty for istate %d", c->self, c->istate); break; } } static void chan_rcvd_ieof1(Channel *c) { debug2("channel %d: rcvd ieof", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); break; case CHAN_OUTPUT_WAIT_IEOF: chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: error("channel %d: protocol error: rcvd_ieof for ostate %d", c->self, c->ostate); break; } } static void chan_write_failed1(Channel *c) { debug2("channel %d: write failed", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: chan_shutdown_write(c); chan_send_oclose1(c); chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF); break; case CHAN_OUTPUT_WAIT_DRAIN: chan_shutdown_write(c); chan_send_oclose1(c); chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: error("channel %d: chan_write_failed for ostate %d", c->self, c->ostate); break; } } void chan_obuf_empty(Channel *c) { debug2("channel %d: obuf empty", c->self); if (buffer_len(&c->output)) { error("channel %d: chan_obuf_empty for non empty buffer", c->self); return; } switch (c->ostate) { case CHAN_OUTPUT_WAIT_DRAIN: chan_shutdown_write(c); if (!compat20) chan_send_oclose1(c); chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: error("channel %d: internal error: obuf_empty for ostate %d", c->self, c->ostate); break; } } static void chan_send_ieof1(Channel *c) { debug2("channel %d: send ieof", c->self); switch (c->istate) { case CHAN_INPUT_OPEN: case CHAN_INPUT_WAIT_DRAIN: packet_start(SSH_MSG_CHANNEL_INPUT_EOF); packet_put_int(c->remote_id); packet_send(); break; default: error("channel %d: cannot send ieof for istate %d", c->self, c->istate); break; } } static void chan_send_oclose1(Channel *c) { debug2("channel %d: send oclose", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: buffer_clear(&c->output); packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); packet_put_int(c->remote_id); packet_send(); break; default: error("channel %d: cannot send oclose for ostate %d", c->self, c->ostate); break; } } /* * the same for SSH2 */ static void chan_rcvd_close2(Channel *c) { debug2("channel %d: rcvd close", c->self); if (!(c->flags & CHAN_LOCAL)) { if (c->flags & CHAN_CLOSE_RCVD) error("channel %d: protocol error: close rcvd twice", c->self); c->flags |= CHAN_CLOSE_RCVD; } if (c->type == SSH_CHANNEL_LARVAL) { /* tear down larval channels immediately */ chan_set_ostate(c, CHAN_OUTPUT_CLOSED); chan_set_istate(c, CHAN_INPUT_CLOSED); return; } switch (c->ostate) { case CHAN_OUTPUT_OPEN: /* * wait until a data from the channel is consumed if a CLOSE * is received */ chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); break; } switch (c->istate) { case CHAN_INPUT_OPEN: chan_shutdown_read(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; case CHAN_INPUT_WAIT_DRAIN: if (!(c->flags & CHAN_LOCAL)) chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; } } void chan_rcvd_eow(Channel *c) { debug2("channel %d: rcvd eow", c->self); switch (c->istate) { case CHAN_INPUT_OPEN: chan_shutdown_read(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; } } static void chan_rcvd_eof2(Channel *c) { debug2("channel %d: rcvd eof", c->self); c->flags |= CHAN_EOF_RCVD; if (c->ostate == CHAN_OUTPUT_OPEN) chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); } static void chan_write_failed2(Channel *c) { debug2("channel %d: write failed", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: chan_shutdown_write(c); if (strcmp(c->ctype, "session") == 0) chan_send_eow2(c); chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: error("channel %d: chan_write_failed for ostate %d", c->self, c->ostate); break; } } static void chan_send_eof2(Channel *c) { debug2("channel %d: send eof", c->self); switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: packet_start(SSH2_MSG_CHANNEL_EOF); packet_put_int(c->remote_id); packet_send(); c->flags |= CHAN_EOF_SENT; break; default: error("channel %d: cannot send eof for istate %d", c->self, c->istate); break; } } static void chan_send_close2(Channel *c) { debug2("channel %d: send close", c->self); if (c->ostate != CHAN_OUTPUT_CLOSED || c->istate != CHAN_INPUT_CLOSED) { error("channel %d: cannot send close for istate/ostate %d/%d", c->self, c->istate, c->ostate); } else if (c->flags & CHAN_CLOSE_SENT) { error("channel %d: already sent close", c->self); } else { packet_start(SSH2_MSG_CHANNEL_CLOSE); packet_put_int(c->remote_id); packet_send(); c->flags |= CHAN_CLOSE_SENT; } } static void chan_send_eow2(Channel *c) { debug2("channel %d: send eow", c->self); if (c->ostate == CHAN_OUTPUT_CLOSED) { error("channel %d: must not sent eow on closed output", c->self); return; } if (!(datafellows & SSH_NEW_OPENSSH)) return; packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring("eow@openssh.com"); packet_put_char(0); packet_send(); } /* shared */ void chan_rcvd_ieof(Channel *c) { if (compat20) chan_rcvd_eof2(c); else chan_rcvd_ieof1(c); if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && buffer_len(&c->output) == 0 && !CHANNEL_EFD_OUTPUT_ACTIVE(c)) chan_obuf_empty(c); } void chan_rcvd_oclose(Channel *c) { if (compat20) chan_rcvd_close2(c); else chan_rcvd_oclose1(c); } void chan_write_failed(Channel *c) { if (compat20) chan_write_failed2(c); else chan_write_failed1(c); } void chan_mark_dead(Channel *c) { c->type = SSH_CHANNEL_ZOMBIE; } int chan_is_dead(Channel *c, int do_send) { if (c->type == SSH_CHANNEL_ZOMBIE) { debug2("channel %d: zombie", c->self); return 1; } if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) return 0; if (!compat20) { debug2("channel %d: is dead", c->self); return 1; } if ((datafellows & SSH_BUG_EXTEOF) && c->extended_usage == CHAN_EXTENDED_WRITE && c->efd != -1 && buffer_len(&c->extended) > 0) { debug2("channel %d: active efd: %d len %d", c->self, c->efd, buffer_len(&c->extended)); return 0; } if (c->flags & CHAN_LOCAL) { debug2("channel %d: is dead (local)", c->self); return 1; } if (!(c->flags & CHAN_CLOSE_SENT)) { if (do_send) { chan_send_close2(c); } else { /* channel would be dead if we sent a close */ if (c->flags & CHAN_CLOSE_RCVD) { debug2("channel %d: almost dead", c->self); return 1; } } } if ((c->flags & CHAN_CLOSE_SENT) && (c->flags & CHAN_CLOSE_RCVD)) { debug2("channel %d: is dead", c->self); return 1; } return 0; } /* helper */ static void chan_shutdown_write(Channel *c) { buffer_clear(&c->output); if (compat20 && c->type == SSH_CHANNEL_LARVAL) return; /* shutdown failure is allowed if write failed already */ debug2("channel %d: close_write", c->self); if (c->sock != -1) { if (shutdown(c->sock, SHUT_WR) < 0) debug2("channel %d: chan_shutdown_write: " "shutdown() failed for fd %d: %.100s", c->self, c->sock, strerror(errno)); } else { if (channel_close_fd(&c->wfd) < 0) logit("channel %d: chan_shutdown_write: " "close() failed for fd %d: %.100s", c->self, c->wfd, strerror(errno)); } } static void chan_shutdown_read(Channel *c) { if (compat20 && c->type == SSH_CHANNEL_LARVAL) return; debug2("channel %d: close_read", c->self); if (c->sock != -1) { /* * shutdown(sock, SHUT_READ) may return ENOTCONN if the * write side has been closed already. (bug on Linux) * HP-UX may return ENOTCONN also. */ if (shutdown(c->sock, SHUT_RD) < 0 && errno != ENOTCONN) error("channel %d: chan_shutdown_read: " "shutdown() failed for fd %d [i%d o%d]: %.100s", c->self, c->sock, c->istate, c->ostate, strerror(errno)); } else { if (channel_close_fd(&c->rfd) < 0) logit("channel %d: chan_shutdown_read: " "close() failed for fd %d: %.100s", c->self, c->rfd, strerror(errno)); } } openssh-7.2p2/nchan.ms010064400017500001750000000075561267006270000131170ustar00djmdjm.\" $OpenBSD: nchan.ms,v 1.8 2003/11/21 11:57:03 djm Exp $ .\" .\" .\" Copyright (c) 1999 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. .\" .TL OpenSSH Channel Close Protocol 1.5 Implementation .SH Channel Input State Diagram .PS reset l=1 s=1.2 ellipsewid=s*ellipsewid boxwid=s*boxwid ellipseht=s*ellipseht S1: ellipse "INPUT" "OPEN" move right 2*l from last ellipse.e S4: ellipse "INPUT" "CLOSED" move down l from last ellipse.s S3: ellipse "INPUT" "WAIT" "OCLOSED" move down l from 1st ellipse.s S2: ellipse "INPUT" "WAIT" "DRAIN" arrow "" "rcvd OCLOSE/" "shutdown_read" "send IEOF" from S1.e to S4.w arrow "ibuf_empty/" "send IEOF" from S2.e to S3.w arrow from S1.s to S2.n box invis "read_failed/" "shutdown_read" with .e at last arrow.c arrow from S3.n to S4.s box invis "rcvd OCLOSE/" "-" with .w at last arrow.c ellipse wid .9*ellipsewid ht .9*ellipseht at S4 arrow "start" "" from S1.w+(-0.5,0) to S1.w arrow from S2.ne to S4.sw box invis "rcvd OCLOSE/ " with .e at last arrow.c box invis " send IEOF" with .w at last arrow.c .PE .SH Channel Output State Diagram .PS S1: ellipse "OUTPUT" "OPEN" move right 2*l from last ellipse.e S3: ellipse "OUTPUT" "WAIT" "IEOF" move down l from last ellipse.s S4: ellipse "OUTPUT" "CLOSED" move down l from 1st ellipse.s S2: ellipse "OUTPUT" "WAIT" "DRAIN" arrow "" "write_failed/" "shutdown_write" "send OCLOSE" from S1.e to S3.w arrow "obuf_empty ||" "write_failed/" "shutdown_write" "send OCLOSE" from S2.e to S4.w arrow from S1.s to S2.n box invis "rcvd IEOF/" "-" with .e at last arrow.c arrow from S3.s to S4.n box invis "rcvd IEOF/" "-" with .w at last arrow.c ellipse wid .9*ellipsewid ht .9*ellipseht at S4 arrow "start" "" from S1.w+(-0.5,0) to S1.w .PE .SH Notes .PP The input buffer is filled with data from the socket (the socket represents the local consumer/producer of the forwarded channel). The data is then sent over the INPUT-end (transmit-end) of the channel to the remote peer. Data sent by the peer is received on the OUTPUT-end (receive-end), saved in the output buffer and written to the socket. .PP If the local protocol instance has forwarded all data on the INPUT-end of the channel, it sends an IEOF message to the peer. If the peer receives the IEOF and has consumed all data he replies with an OCLOSE. When the local instance receives the OCLOSE he considers the INPUT-half of the channel closed. The peer has his OUTOUT-half closed. .PP A channel can be deallocated by a protocol instance if both the INPUT- and the OUTOUT-half on his side of the channel are closed. Note that when an instance is unable to consume the received data, he is permitted to send an OCLOSE before the matching IEOF is received. openssh-7.2p2/nchan2.ms010064400017500001750000000066021267006270000131700ustar00djmdjm.\" $OpenBSD: nchan2.ms,v 1.4 2008/05/15 23:52:24 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. .\" .TL OpenSSH Channel Close Protocol 2.0 Implementation .SH Channel Input State Diagram .PS reset l=1 s=1.2 ellipsewid=s*ellipsewid boxwid=s*boxwid ellipseht=s*ellipseht S1: ellipse "INPUT" "OPEN" move right 2*l from last ellipse.e S3: ellipse invis move down l from last ellipse.s S4: ellipse "INPUT" "CLOSED" move down l from 1st ellipse.s S2: ellipse "INPUT" "WAIT" "DRAIN" arrow from S1.e to S4.n box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w arrow from S1.s to S2.n box invis "read_failed ||" "rcvd EOW/" "shutdown_read" with .e at last arrow.c ellipse wid .9*ellipsewid ht .9*ellipseht at S4 arrow "start" "" from S1.w+(-0.5,0) to S1.w .PE .SH Channel Output State Diagram .PS S1: ellipse "OUTPUT" "OPEN" move right 2*l from last ellipse.e S3: ellipse invis move down l from last ellipse.s S4: ellipse "OUTPUT" "CLOSED" move down l from 1st ellipse.s S2: ellipse "OUTPUT" "WAIT" "DRAIN" arrow from S1.e to S4.n box invis "write_failed/" "shutdown_write" "send EOW" with .sw at last arrow.c arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w arrow from S1.s to S2.n box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c ellipse wid .9*ellipsewid ht .9*ellipseht at S4 arrow "start" "" from S1.w+(-0.5,0) to S1.w .PE .SH Notes .PP The input buffer is filled with data from the socket (the socket represents the local consumer/producer of the forwarded channel). The data is then sent over the INPUT-end (transmit-end) of the channel to the remote peer. Data sent by the peer is received on the OUTPUT-end (receive-end), saved in the output buffer and written to the socket. .PP If the local protocol instance has forwarded all data on the INPUT-end of the channel, it sends an EOF message to the peer. .PP A CLOSE message is sent to the peer if both the INPUT- and the OUTOUT-half of the local end of the channel are closed. .PP The channel can be deallocated by a protocol instance if a CLOSE message he been both sent and received. openssh-7.2p2/opacket.c010064400017500001750000000135311267006270000132470ustar00djmdjm/* Written by Markus Friedl. Placed in the public domain. */ #include "includes.h" #include "ssherr.h" #include "packet.h" #include "log.h" struct ssh *active_state, *backup_state; /* Map old to new API */ void ssh_packet_start(struct ssh *ssh, u_char type) { int r; if ((r = sshpkt_start(ssh, type)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_char(struct ssh *ssh, int value) { u_char ch = value; int r; if ((r = sshpkt_put_u8(ssh, ch)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_int(struct ssh *ssh, u_int value) { int r; if ((r = sshpkt_put_u32(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_int64(struct ssh *ssh, u_int64_t value) { int r; if ((r = sshpkt_put_u64(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_string(struct ssh *ssh, const void *buf, u_int len) { int r; if ((r = sshpkt_put_string(ssh, buf, len)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_cstring(struct ssh *ssh, const char *str) { int r; if ((r = sshpkt_put_cstring(ssh, str)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } void ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len) { int r; if ((r = sshpkt_put(ssh, buf, len)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } #ifdef WITH_SSH1 void ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value) { int r; if ((r = sshpkt_put_bignum1(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } #endif #ifdef WITH_OPENSSL void ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value) { int r; if ((r = sshpkt_put_bignum2(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } # ifdef OPENSSL_HAS_ECC void ssh_packet_put_ecpoint(struct ssh *ssh, const EC_GROUP *curve, const EC_POINT *point) { int r; if ((r = sshpkt_put_ec(ssh, point, curve)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } # endif #endif /* WITH_OPENSSL */ void ssh_packet_send(struct ssh *ssh) { int r; if ((r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } u_int ssh_packet_get_char(struct ssh *ssh) { u_char ch; int r; if ((r = sshpkt_get_u8(ssh, &ch)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return ch; } u_int ssh_packet_get_int(struct ssh *ssh) { u_int val; int r; if ((r = sshpkt_get_u32(ssh, &val)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return val; } u_int64_t ssh_packet_get_int64(struct ssh *ssh) { u_int64_t val; int r; if ((r = sshpkt_get_u64(ssh, &val)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return val; } #ifdef WITH_SSH1 void ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value) { int r; if ((r = sshpkt_get_bignum1(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } #endif #ifdef WITH_OPENSSL void ssh_packet_get_bignum2(struct ssh *ssh, BIGNUM * value) { int r; if ((r = sshpkt_get_bignum2(ssh, value)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } # ifdef OPENSSL_HAS_ECC void ssh_packet_get_ecpoint(struct ssh *ssh, const EC_GROUP *curve, EC_POINT *point) { int r; if ((r = sshpkt_get_ec(ssh, point, curve)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } # endif #endif /* WITH_OPENSSL */ void * ssh_packet_get_string(struct ssh *ssh, u_int *length_ptr) { int r; size_t len; u_char *val; if ((r = sshpkt_get_string(ssh, &val, &len)) != 0) fatal("%s: %s", __func__, ssh_err(r)); if (length_ptr != NULL) *length_ptr = (u_int)len; return val; } const void * ssh_packet_get_string_ptr(struct ssh *ssh, u_int *length_ptr) { int r; size_t len; const u_char *val; if ((r = sshpkt_get_string_direct(ssh, &val, &len)) != 0) fatal("%s: %s", __func__, ssh_err(r)); if (length_ptr != NULL) *length_ptr = (u_int)len; return val; } char * ssh_packet_get_cstring(struct ssh *ssh, u_int *length_ptr) { int r; size_t len; char *val; if ((r = sshpkt_get_cstring(ssh, &val, &len)) != 0) fatal("%s: %s", __func__, ssh_err(r)); if (length_ptr != NULL) *length_ptr = (u_int)len; return val; } /* Old API, that had to be reimplemented */ void packet_set_connection(int fd_in, int fd_out) { active_state = ssh_packet_set_connection(active_state, fd_in, fd_out); if (active_state == NULL) fatal("%s: ssh_packet_set_connection failed", __func__); } u_int packet_get_char(void) { return (ssh_packet_get_char(active_state)); } u_int packet_get_int(void) { return (ssh_packet_get_int(active_state)); } int packet_read_seqnr(u_int32_t *seqnr) { u_char type; int r; if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0) sshpkt_fatal(active_state, __func__, r); return type; } int packet_read_poll_seqnr(u_int32_t *seqnr) { u_char type; int r; if ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr))) sshpkt_fatal(active_state, __func__, r); return type; } void packet_close(void) { ssh_packet_close(active_state); active_state = NULL; } void packet_process_incoming(const char *buf, u_int len) { int r; if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0) sshpkt_fatal(active_state, __func__, r); } void packet_write_wait(void) { int r; if ((r = ssh_packet_write_wait(active_state)) != 0) sshpkt_fatal(active_state, __func__, r); } void packet_write_poll(void) { int r; if ((r = ssh_packet_write_poll(active_state)) != 0) sshpkt_fatal(active_state, __func__, r); } void packet_read_expect(int expected_type) { int r; if ((r = ssh_packet_read_expect(active_state, expected_type)) != 0) sshpkt_fatal(active_state, __func__, r); } void packet_disconnect(const char *fmt, ...) { char buf[1024]; va_list args; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); ssh_packet_disconnect(active_state, "%s", buf); } void packet_send_debug(const char *fmt, ...) { char buf[1024]; va_list args; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); ssh_packet_send_debug(active_state, "%s", buf); } openssh-7.2p2/opacket.h010064400017500001750000000147101267006270000132540ustar00djmdjm#ifndef _OPACKET_H /* Written by Markus Friedl. Placed in the public domain. */ /* Map old to new API */ void ssh_packet_start(struct ssh *, u_char); void ssh_packet_put_char(struct ssh *, int ch); void ssh_packet_put_int(struct ssh *, u_int value); void ssh_packet_put_int64(struct ssh *, u_int64_t value); void ssh_packet_put_bignum(struct ssh *, BIGNUM * value); void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); void ssh_packet_put_cstring(struct ssh *, const char *str); void ssh_packet_put_raw(struct ssh *, const void *buf, u_int len); void ssh_packet_send(struct ssh *); u_int ssh_packet_get_char(struct ssh *); u_int ssh_packet_get_int(struct ssh *); u_int64_t ssh_packet_get_int64(struct ssh *); void ssh_packet_get_bignum(struct ssh *, BIGNUM * value); void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value); void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *); void *ssh_packet_get_string(struct ssh *, u_int *length_ptr); char *ssh_packet_get_cstring(struct ssh *, u_int *length_ptr); /* don't allow remaining bytes after the end of the message */ #define ssh_packet_check_eom(ssh) \ do { \ int _len = ssh_packet_remaining(ssh); \ if (_len > 0) { \ logit("Packet integrity error (%d bytes remaining) at %s:%d", \ _len ,__FILE__, __LINE__); \ ssh_packet_disconnect(ssh, \ "Packet integrity error."); \ } \ } while (0) /* old API */ void packet_close(void); u_int packet_get_char(void); u_int packet_get_int(void); void packet_set_connection(int, int); int packet_read_seqnr(u_int32_t *); int packet_read_poll_seqnr(u_int32_t *); void packet_process_incoming(const char *buf, u_int len); void packet_write_wait(void); void packet_write_poll(void); void packet_read_expect(int expected_type); #define packet_set_timeout(timeout, count) \ ssh_packet_set_timeout(active_state, (timeout), (count)) #define packet_connection_is_on_socket() \ ssh_packet_connection_is_on_socket(active_state) #define packet_set_nonblocking() \ ssh_packet_set_nonblocking(active_state) #define packet_get_connection_in() \ ssh_packet_get_connection_in(active_state) #define packet_get_connection_out() \ ssh_packet_get_connection_out(active_state) #define packet_set_protocol_flags(protocol_flags) \ ssh_packet_set_protocol_flags(active_state, (protocol_flags)) #define packet_get_protocol_flags() \ ssh_packet_get_protocol_flags(active_state) #define packet_start_compression(level) \ ssh_packet_start_compression(active_state, (level)) #define packet_set_encryption_key(key, keylen, number) \ ssh_packet_set_encryption_key(active_state, (key), (keylen), (number)) #define packet_start(type) \ ssh_packet_start(active_state, (type)) #define packet_put_char(value) \ ssh_packet_put_char(active_state, (value)) #define packet_put_int(value) \ ssh_packet_put_int(active_state, (value)) #define packet_put_int64(value) \ ssh_packet_put_int64(active_state, (value)) #define packet_put_string( buf, len) \ ssh_packet_put_string(active_state, (buf), (len)) #define packet_put_cstring(str) \ ssh_packet_put_cstring(active_state, (str)) #define packet_put_raw(buf, len) \ ssh_packet_put_raw(active_state, (buf), (len)) #define packet_put_bignum(value) \ ssh_packet_put_bignum(active_state, (value)) #define packet_put_bignum2(value) \ ssh_packet_put_bignum2(active_state, (value)) #define packet_send() \ ssh_packet_send(active_state) #define packet_read() \ ssh_packet_read(active_state) #define packet_get_int64() \ ssh_packet_get_int64(active_state) #define packet_get_bignum(value) \ ssh_packet_get_bignum(active_state, (value)) #define packet_get_bignum2(value) \ ssh_packet_get_bignum2(active_state, (value)) #define packet_remaining() \ ssh_packet_remaining(active_state) #define packet_get_string(length_ptr) \ ssh_packet_get_string(active_state, (length_ptr)) #define packet_get_string_ptr(length_ptr) \ ssh_packet_get_string_ptr(active_state, (length_ptr)) #define packet_get_cstring(length_ptr) \ ssh_packet_get_cstring(active_state, (length_ptr)) void packet_send_debug(const char *, ...) __attribute__((format(printf, 1, 2))); void packet_disconnect(const char *, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); #define packet_have_data_to_write() \ ssh_packet_have_data_to_write(active_state) #define packet_not_very_much_data_to_write() \ ssh_packet_not_very_much_data_to_write(active_state) #define packet_set_interactive(interactive, qos_interactive, qos_bulk) \ ssh_packet_set_interactive(active_state, (interactive), (qos_interactive), (qos_bulk)) #define packet_is_interactive() \ ssh_packet_is_interactive(active_state) #define packet_set_maxsize(s) \ ssh_packet_set_maxsize(active_state, (s)) #define packet_inc_alive_timeouts() \ ssh_packet_inc_alive_timeouts(active_state) #define packet_set_alive_timeouts(ka) \ ssh_packet_set_alive_timeouts(active_state, (ka)) #define packet_get_maxsize() \ ssh_packet_get_maxsize(active_state) #define packet_add_padding(pad) \ sshpkt_add_padding(active_state, (pad)) #define packet_send_ignore(nbytes) \ ssh_packet_send_ignore(active_state, (nbytes)) #define packet_set_server() \ ssh_packet_set_server(active_state) #define packet_set_authenticated() \ ssh_packet_set_authenticated(active_state) #define packet_get_input() \ ssh_packet_get_input(active_state) #define packet_get_output() \ ssh_packet_get_output(active_state) #define packet_set_compress_hooks(ctx, allocfunc, freefunc) \ ssh_packet_set_compress_hooks(active_state, ctx, \ allocfunc, freefunc); #define packet_check_eom() \ ssh_packet_check_eom(active_state) #define set_newkeys(mode) \ ssh_set_newkeys(active_state, (mode)) #define packet_get_state(m) \ ssh_packet_get_state(active_state, m) #define packet_set_state(m) \ ssh_packet_set_state(active_state, m) #if 0 #define get_remote_ipaddr() \ ssh_remote_ipaddr(active_state) #endif #define packet_get_raw(lenp) \ sshpkt_ptr(active_state, lenp) #define packet_get_ecpoint(c,p) \ ssh_packet_get_ecpoint(active_state, c, p) #define packet_put_ecpoint(c,p) \ ssh_packet_put_ecpoint(active_state, c, p) #define packet_get_rekey_timeout() \ ssh_packet_get_rekey_timeout(active_state) #define packet_set_rekey_limits(x,y) \ ssh_packet_set_rekey_limits(active_state, x, y) #define packet_get_bytes(x,y) \ ssh_packet_get_bytes(active_state, x, y) #endif /* _OPACKET_H */ openssh-7.2p2/openbsd-compat004075500017500001750000000000001267006270000143115ustar00djmdjmopenssh-7.2p2/openbsd-compat/.cvsignore010064400017500001750000000000111267006270000163550ustar00djmdjmMakefile openssh-7.2p2/openbsd-compat/Makefile.in010064400017500001750000000027551267006270000164430ustar00djmdjm# $Id: Makefile.in,v 1.56 2014/09/30 23:43:08 djm Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ srcdir=@srcdir@ top_srcdir=@top_srcdir@ VPATH=@srcdir@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ LIBS=@LIBS@ AR=@AR@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< all: libopenbsd-compat.a $(COMPAT): ../config.h $(OPENBSD): ../config.h $(PORTS): ../config.h libopenbsd-compat.a: $(COMPAT) $(OPENBSD) $(PORTS) $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORTS) $(RANLIB) $@ clean: rm -f *.o *.a core distclean: clean rm -f Makefile *~ openssh-7.2p2/openbsd-compat/arc4random.c010064400017500001750000000155411267006270000165710ustar00djmdjm/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */ /* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ /* * Copyright (c) 1996, David Mazieres * Copyright (c) 2008, Damien Miller * Copyright (c) 2013, Markus Friedl * * 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. */ /* * ChaCha based random number generator for OpenBSD. */ #include "includes.h" #include #include #include #include #include #ifndef HAVE_ARC4RANDOM #ifdef WITH_OPENSSL #include #include #endif #include "log.h" #define KEYSTREAM_ONLY #include "chacha_private.h" #ifdef __GNUC__ #define inline __inline #else /* !__GNUC__ */ #define inline #endif /* !__GNUC__ */ /* OpenSSH isn't multithreaded */ #define _ARC4_LOCK() #define _ARC4_UNLOCK() #define KEYSZ 32 #define IVSZ 8 #define BLOCKSZ 64 #define RSBUFSZ (16*BLOCKSZ) static int rs_initialized; static pid_t rs_stir_pid; static chacha_ctx rs; /* chacha context for random keystream */ static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ static size_t rs_have; /* valid bytes at end of rs_buf */ static size_t rs_count; /* bytes till reseed */ static inline void _rs_rekey(u_char *dat, size_t datlen); static inline void _rs_init(u_char *buf, size_t n) { if (n < KEYSZ + IVSZ) return; chacha_keysetup(&rs, buf, KEYSZ * 8, 0); chacha_ivsetup(&rs, buf + KEYSZ); } #ifndef WITH_OPENSSL #define SSH_RANDOM_DEV "/dev/urandom" /* XXX use getrandom() if supported on Linux */ static void getrnd(u_char *s, size_t len) { int fd; ssize_t r; size_t o = 0; if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); while (o < len) { r = read(fd, s + o, len - o); if (r < 0) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) continue; fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); } o += r; } close(fd); } #endif static void _rs_stir(void) { u_char rnd[KEYSZ + IVSZ]; #ifdef WITH_OPENSSL if (RAND_bytes(rnd, sizeof(rnd)) <= 0) fatal("Couldn't obtain random bytes (error %ld)", ERR_get_error()); #else getrnd(rnd, sizeof(rnd)); #endif if (!rs_initialized) { rs_initialized = 1; _rs_init(rnd, sizeof(rnd)); } else _rs_rekey(rnd, sizeof(rnd)); explicit_bzero(rnd, sizeof(rnd)); /* invalidate rs_buf */ rs_have = 0; memset(rs_buf, 0, RSBUFSZ); rs_count = 1600000; } static inline void _rs_stir_if_needed(size_t len) { pid_t pid = getpid(); if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) { rs_stir_pid = pid; _rs_stir(); } else rs_count -= len; } static inline void _rs_rekey(u_char *dat, size_t datlen) { #ifndef KEYSTREAM_ONLY memset(rs_buf, 0,RSBUFSZ); #endif /* fill rs_buf with the keystream */ chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); /* mix in optional user provided data */ if (dat) { size_t i, m; m = MIN(datlen, KEYSZ + IVSZ); for (i = 0; i < m; i++) rs_buf[i] ^= dat[i]; } /* immediately reinit for backtracking resistance */ _rs_init(rs_buf, KEYSZ + IVSZ); memset(rs_buf, 0, KEYSZ + IVSZ); rs_have = RSBUFSZ - KEYSZ - IVSZ; } static inline void _rs_random_buf(void *_buf, size_t n) { u_char *buf = (u_char *)_buf; size_t m; _rs_stir_if_needed(n); while (n > 0) { if (rs_have > 0) { m = MIN(n, rs_have); memcpy(buf, rs_buf + RSBUFSZ - rs_have, m); memset(rs_buf + RSBUFSZ - rs_have, 0, m); buf += m; n -= m; rs_have -= m; } if (rs_have == 0) _rs_rekey(NULL, 0); } } static inline void _rs_random_u32(u_int32_t *val) { _rs_stir_if_needed(sizeof(*val)); if (rs_have < sizeof(*val)) _rs_rekey(NULL, 0); memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val)); memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val)); rs_have -= sizeof(*val); return; } void arc4random_stir(void) { _ARC4_LOCK(); _rs_stir(); _ARC4_UNLOCK(); } void arc4random_addrandom(u_char *dat, int datlen) { int m; _ARC4_LOCK(); if (!rs_initialized) _rs_stir(); while (datlen > 0) { m = MIN(datlen, KEYSZ + IVSZ); _rs_rekey(dat, m); dat += m; datlen -= m; } _ARC4_UNLOCK(); } u_int32_t arc4random(void) { u_int32_t val; _ARC4_LOCK(); _rs_random_u32(&val); _ARC4_UNLOCK(); return val; } /* * If we are providing arc4random, then we can provide a more efficient * arc4random_buf(). */ # ifndef HAVE_ARC4RANDOM_BUF void arc4random_buf(void *buf, size_t n) { _ARC4_LOCK(); _rs_random_buf(buf, n); _ARC4_UNLOCK(); } # endif /* !HAVE_ARC4RANDOM_BUF */ #endif /* !HAVE_ARC4RANDOM */ /* arc4random_buf() that uses platform arc4random() */ #if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) void arc4random_buf(void *_buf, size_t n) { size_t i; u_int32_t r = 0; char *buf = (char *)_buf; for (i = 0; i < n; i++) { if (i % 4 == 0) r = arc4random(); buf[i] = r & 0xff; r >>= 8; } explicit_bzero(&r, sizeof(r)); } #endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ #ifndef HAVE_ARC4RANDOM_UNIFORM /* * Calculate a uniformly distributed random number less than upper_bound * avoiding "modulo bias". * * Uniformity is achieved by generating new random numbers until the one * returned is outside the range [0, 2**32 % upper_bound). This * guarantees the selected random number will be inside * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) * after reduction modulo upper_bound. */ u_int32_t arc4random_uniform(u_int32_t upper_bound) { u_int32_t r, min; if (upper_bound < 2) return 0; /* 2**32 % x == (2**32 - x) % x */ min = -upper_bound % upper_bound; /* * This could theoretically loop forever but each retry has * p > 0.5 (worst case, usually far better) of selecting a * number inside the range we need, so it should rarely need * to re-roll. */ for (;;) { r = arc4random(); if (r >= min) break; } return r % upper_bound; } #endif /* !HAVE_ARC4RANDOM_UNIFORM */ #if 0 /*-------- Test code for i386 --------*/ #include #include int main(int argc, char **argv) { const int iter = 1000000; int i; pctrval v; v = rdtsc(); for (i = 0; i < iter; i++) arc4random(); v = rdtsc() - v; v /= iter; printf("%qd cycles\n", v); exit(0); } #endif openssh-7.2p2/openbsd-compat/base64.c010064400017500001750000000243761267006270000156310ustar00djmdjm/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ /* * Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /* OPENBSD ORIGINAL: lib/libc/net/base64.c */ #include "includes.h" #if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) #include #include #include #include #include #include #include #include #include #include "base64.h" static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) The following encoding technique is taken from RFC 1521 by Borenstein and Freed. It is reproduced here in a slightly edited form for convenience. A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. (The extra 65th character, "=", is used to signify a special processing function.) The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base64 alphabet. Each 6-bit group is used as an index into an array of 64 printable characters. The character referenced by the index is placed in the output string. Table 1: The Base64 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y Special processing is performed if fewer than 24 bits are available at the end of the data being encoded. A full encoding quantum is always completed at the end of a quantity. When fewer than 24 input bits are available in an input group, zero bits are added (on the right) to form an integral number of 6-bit groups. Padding at the end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the ------------------------------------------------- following cases can arise: (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no "=" padding, (2) the final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two "=" padding characters, or (3) the final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one "=" padding character. */ #if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) int b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) { size_t datalength = 0; u_char input[3]; u_char output[4]; u_int i; while (2 < srclength) { input[0] = *src++; input[1] = *src++; input[2] = *src++; srclength -= 3; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; if (datalength + 4 > targsize) return (-1); target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; target[datalength++] = Base64[output[2]]; target[datalength++] = Base64[output[3]]; } /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) input[i] = *src++; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); if (datalength + 4 > targsize) return (-1); target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; if (srclength == 1) target[datalength++] = Pad64; else target[datalength++] = Base64[output[2]]; target[datalength++] = Pad64; } if (datalength >= targsize) return (-1); target[datalength] = '\0'; /* Returned value doesn't count \0. */ return (datalength); } #endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ #if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) /* skips all whitespace anywhere. converts characters, four at a time, starting at (or after) src from base - 64 numbers into three 8 bit bytes in the target area. it returns the number of data bytes stored at the target, or -1 on error. */ int b64_pton(char const *src, u_char *target, size_t targsize) { u_int tarindex, state; int ch; char *pos; state = 0; tarindex = 0; while ((ch = *src++) != '\0') { if (isspace(ch)) /* Skip whitespace anywhere. */ continue; if (ch == Pad64) break; pos = strchr(Base64, ch); if (pos == 0) /* A non-base64 character. */ return (-1); switch (state) { case 0: if (target) { if (tarindex >= targsize) return (-1); target[tarindex] = (pos - Base64) << 2; } state = 1; break; case 1: if (target) { if (tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 4; target[tarindex+1] = ((pos - Base64) & 0x0f) << 4 ; } tarindex++; state = 2; break; case 2: if (target) { if (tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 2; target[tarindex+1] = ((pos - Base64) & 0x03) << 6; } tarindex++; state = 3; break; case 3: if (target) { if (tarindex >= targsize) return (-1); target[tarindex] |= (pos - Base64); } tarindex++; state = 0; break; } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for (; ch != '\0'; ch = *src++) if (!isspace(ch)) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for (; ch != '\0'; ch = *src++) if (!isspace(ch)) return (-1); /* * Now make sure for cases 2 and 3 that the "extra" * bits that slopped past the last full byte were * zeros. If we don't check them, they become a * subliminal channel. */ if (target && target[tarindex] != 0) return (-1); } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } #endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ #endif openssh-7.2p2/openbsd-compat/base64.h010064400017500001750000000054051267006270000156260ustar00djmdjm/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ /* * Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #ifndef _BSD_BASE64_H #define _BSD_BASE64_H #include "includes.h" #ifndef HAVE___B64_NTOP # ifndef HAVE_B64_NTOP int b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); # endif /* !HAVE_B64_NTOP */ # define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d) #endif /* HAVE___B64_NTOP */ #ifndef HAVE___B64_PTON # ifndef HAVE_B64_PTON int b64_pton(char const *src, u_char *target, size_t targsize); # endif /* !HAVE_B64_PTON */ # define __b64_pton(a,b,c) b64_pton(a,b,c) #endif /* HAVE___B64_PTON */ #endif /* _BSD_BASE64_H */ openssh-7.2p2/openbsd-compat/basename.c010064400017500001750000000034341267006270000163100ustar00djmdjm/* $OpenBSD: basename.c,v 1.14 2005/08/08 08:05:33 espie Exp $ */ /* * Copyright (c) 1997, 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/basename.c */ #include "includes.h" #ifndef HAVE_BASENAME #include #include char * basename(const char *path) { static char bname[MAXPATHLEN]; size_t len; const char *endp, *startp; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { bname[0] = '.'; bname[1] = '\0'; return (bname); } /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; /* All slashes becomes "/" */ if (endp == path && *endp == '/') { bname[0] = '/'; bname[1] = '\0'; return (bname); } /* Find the start of the base */ startp = endp; while (startp > path && *(startp - 1) != '/') startp--; len = endp - startp + 1; if (len >= sizeof(bname)) { errno = ENAMETOOLONG; return (NULL); } memcpy(bname, startp, len); bname[len] = '\0'; return (bname); } #endif /* !defined(HAVE_BASENAME) */ openssh-7.2p2/openbsd-compat/bcrypt_pbkdf.c010064400017500001750000000126061267006270000172070ustar00djmdjm/* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */ /* * Copyright (c) 2013 Ted Unangst * * 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" #ifndef HAVE_BCRYPT_PBKDF #include #include #ifdef HAVE_STDLIB_H # include #endif #include #ifdef HAVE_BLF_H # include #endif #include "crypto_api.h" #ifdef SHA512_DIGEST_LENGTH # undef SHA512_DIGEST_LENGTH #endif #define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES #define MINIMUM(a,b) (((a) < (b)) ? (a) : (b)) /* * pkcs #5 pbkdf2 implementation using the "bcrypt" hash * * The bcrypt hash function is derived from the bcrypt password hashing * function with the following modifications: * 1. The input password and salt are preprocessed with SHA512. * 2. The output length is expanded to 256 bits. * 3. Subsequently the magic string to be encrypted is lengthened and modifed * to "OxychromaticBlowfishSwatDynamite" * 4. The hash function is defined to perform 64 rounds of initial state * expansion. (More rounds are performed by iterating the hash.) * * Note that this implementation pulls the SHA512 operations into the caller * as a performance optimization. * * One modification from official pbkdf2. Instead of outputting key material * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an * attacker can merely run once through the outer loop, but the user * always runs it twice. Shuffling output bytes requires computing the * entirety of the key material to assemble any subkey. This is something a * wise caller could do; we just do it for you. */ #define BCRYPT_WORDS 8 #define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4) static void bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) { blf_ctx state; u_int8_t ciphertext[BCRYPT_HASHSIZE] = "OxychromaticBlowfishSwatDynamite"; uint32_t cdata[BCRYPT_WORDS]; int i; uint16_t j; size_t shalen = SHA512_DIGEST_LENGTH; /* key expansion */ Blowfish_initstate(&state); Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen); for (i = 0; i < 64; i++) { Blowfish_expand0state(&state, sha2salt, shalen); Blowfish_expand0state(&state, sha2pass, shalen); } /* encryption */ j = 0; for (i = 0; i < BCRYPT_WORDS; i++) cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), &j); for (i = 0; i < 64; i++) blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); /* copy out */ for (i = 0; i < BCRYPT_WORDS; i++) { out[4 * i + 3] = (cdata[i] >> 24) & 0xff; out[4 * i + 2] = (cdata[i] >> 16) & 0xff; out[4 * i + 1] = (cdata[i] >> 8) & 0xff; out[4 * i + 0] = cdata[i] & 0xff; } /* zap */ explicit_bzero(ciphertext, sizeof(ciphertext)); explicit_bzero(cdata, sizeof(cdata)); explicit_bzero(&state, sizeof(state)); } int bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t saltlen, u_int8_t *key, size_t keylen, unsigned int rounds) { u_int8_t sha2pass[SHA512_DIGEST_LENGTH]; u_int8_t sha2salt[SHA512_DIGEST_LENGTH]; u_int8_t out[BCRYPT_HASHSIZE]; u_int8_t tmpout[BCRYPT_HASHSIZE]; u_int8_t *countsalt; size_t i, j, amt, stride; uint32_t count; size_t origkeylen = keylen; /* nothing crazy */ if (rounds < 1) return -1; if (passlen == 0 || saltlen == 0 || keylen == 0 || keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20) return -1; if ((countsalt = calloc(1, saltlen + 4)) == NULL) return -1; stride = (keylen + sizeof(out) - 1) / sizeof(out); amt = (keylen + stride - 1) / stride; memcpy(countsalt, salt, saltlen); /* collapse password */ crypto_hash_sha512(sha2pass, pass, passlen); /* generate key, sizeof(out) at a time */ for (count = 1; keylen > 0; count++) { countsalt[saltlen + 0] = (count >> 24) & 0xff; countsalt[saltlen + 1] = (count >> 16) & 0xff; countsalt[saltlen + 2] = (count >> 8) & 0xff; countsalt[saltlen + 3] = count & 0xff; /* first round, salt is salt */ crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); bcrypt_hash(sha2pass, sha2salt, tmpout); memcpy(out, tmpout, sizeof(out)); for (i = 1; i < rounds; i++) { /* subsequent rounds, salt is previous output */ crypto_hash_sha512(sha2salt, tmpout, sizeof(tmpout)); bcrypt_hash(sha2pass, sha2salt, tmpout); for (j = 0; j < sizeof(out); j++) out[j] ^= tmpout[j]; } /* * pbkdf2 deviation: output the key material non-linearly. */ amt = MINIMUM(amt, keylen); for (i = 0; i < amt; i++) { size_t dest = i * stride + (count - 1); if (dest >= origkeylen) break; key[dest] = out[i]; } keylen -= i; } /* zap */ explicit_bzero(out, sizeof(out)); free(countsalt); return 0; } #endif /* HAVE_BCRYPT_PBKDF */ openssh-7.2p2/openbsd-compat/bindresvport.c010064400017500001750000000063371267006270000172630ustar00djmdjm/* This file has be substantially modified from the original OpenBSD source */ /* $OpenBSD: bindresvport.c,v 1.17 2005/12/21 01:40:22 millert Exp $ */ /* * Copyright 1996, Jason Downs. All rights reserved. * Copyright 1998, Theo de Raadt. All rights reserved. * Copyright 2000, Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* OPENBSD ORIGINAL: lib/libc/rpc/bindresvport.c */ #include "includes.h" #ifndef HAVE_BINDRESVPORT_SA #include #include #include #include #include #include #define STARTPORT 600 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) /* * Bind a socket to a privileged IP port */ int bindresvport_sa(int sd, struct sockaddr *sa) { int error, af; struct sockaddr_storage myaddr; struct sockaddr_in *in; struct sockaddr_in6 *in6; u_int16_t *portp; u_int16_t port; socklen_t salen; int i; if (sa == NULL) { memset(&myaddr, 0, sizeof(myaddr)); sa = (struct sockaddr *)&myaddr; if (getsockname(sd, sa, &salen) == -1) return -1; /* errno is correctly set */ af = sa->sa_family; memset(&myaddr, 0, salen); } else af = sa->sa_family; if (af == AF_INET) { in = (struct sockaddr_in *)sa; salen = sizeof(struct sockaddr_in); portp = &in->sin_port; } else if (af == AF_INET6) { in6 = (struct sockaddr_in6 *)sa; salen = sizeof(struct sockaddr_in6); portp = &in6->sin6_port; } else { errno = EPFNOSUPPORT; return (-1); } sa->sa_family = af; port = ntohs(*portp); if (port == 0) port = arc4random_uniform(NPORTS) + STARTPORT; /* Avoid warning */ error = -1; for(i = 0; i < NPORTS; i++) { *portp = htons(port); error = bind(sd, sa, salen); /* Terminate on success */ if (error == 0) break; /* Terminate on errors, except "address already in use" */ if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) break; port++; if (port > ENDPORT) port = STARTPORT; } return (error); } #endif /* HAVE_BINDRESVPORT_SA */ openssh-7.2p2/openbsd-compat/blf.h010064400017500001750000000067661267006270000153200ustar00djmdjm/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */ /* * Blowfish - a fast block cipher designed by Bruce Schneier * * Copyright 1997 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Niels Provos. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 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 _BLF_H_ #define _BLF_H_ #include "includes.h" #if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) /* Schneier specifies a maximum key length of 56 bytes. * This ensures that every key bit affects every cipher * bit. However, the subkeys can hold up to 72 bytes. * Warning: For normal blowfish encryption only 56 bytes * of the key affect all cipherbits. */ #define BLF_N 16 /* Number of Subkeys */ #define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ #define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */ /* Blowfish context */ typedef struct BlowfishContext { u_int32_t S[4][256]; /* S-Boxes */ u_int32_t P[BLF_N + 2]; /* Subkeys */ } blf_ctx; /* Raw access to customized Blowfish * blf_key is just: * Blowfish_initstate( state ) * Blowfish_expand0state( state, key, keylen ) */ void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_initstate(blf_ctx *); void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t); void Blowfish_expandstate (blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t); /* Standard Blowfish */ void blf_key(blf_ctx *, const u_int8_t *, u_int16_t); void blf_enc(blf_ctx *, u_int32_t *, u_int16_t); void blf_dec(blf_ctx *, u_int32_t *, u_int16_t); void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); /* Converts u_int8_t to u_int32_t */ u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *); #endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */ #endif /* _BLF_H */ openssh-7.2p2/openbsd-compat/blowfish.c010064400017500001750000000561571267006270000163640ustar00djmdjm/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ /* * Blowfish block cipher for OpenBSD * Copyright 1997 Niels Provos * All rights reserved. * * Implementation advice by David Mazieres . * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Niels Provos. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This code is derived from section 14.3 and the given source * in section V of Applied Cryptography, second edition. * Blowfish is an unpatented fast block cipher designed by * Bruce Schneier. */ #include "includes.h" #if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) #if 0 #include /* used for debugging */ #include #endif #include #ifdef HAVE_BLF_H #include #endif #undef inline #ifdef __GNUC__ #define inline __inline #else /* !__GNUC__ */ #define inline #endif /* !__GNUC__ */ /* Function for Feistel Networks */ #define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ + (s)[0x100 + (((x)>>16)&0xFF)]) \ ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ + (s)[0x300 + ( (x) &0xFF)]) #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) void Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) { u_int32_t Xl; u_int32_t Xr; u_int32_t *s = c->S[0]; u_int32_t *p = c->P; Xl = *xl; Xr = *xr; Xl ^= p[0]; BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); *xl = Xr ^ p[17]; *xr = Xl; } void Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) { u_int32_t Xl; u_int32_t Xr; u_int32_t *s = c->S[0]; u_int32_t *p = c->P; Xl = *xl; Xr = *xr; Xl ^= p[17]; BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); *xl = Xr ^ p[0]; *xr = Xl; } void Blowfish_initstate(blf_ctx *c) { /* P-box and S-box tables initialized with digits of Pi */ static const blf_ctx initstate = { { { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, { 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, { 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, { 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} }, { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b } }; *c = initstate; } u_int32_t Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current) { u_int8_t i; u_int16_t j; u_int32_t temp; temp = 0x00000000; j = *current; for (i = 0; i < 4; i++, j++) { if (j >= databytes) j = 0; temp = (temp << 8) | data[j]; } *current = j; return temp; } void Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) { u_int16_t i; u_int16_t j; u_int16_t k; u_int32_t temp; u_int32_t datal; u_int32_t datar; j = 0; for (i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; datal = 0x00000000; datar = 0x00000000; for (i = 0; i < BLF_N + 2; i += 2) { Blowfish_encipher(c, &datal, &datar); c->P[i] = datal; c->P[i + 1] = datar; } for (i = 0; i < 4; i++) { for (k = 0; k < 256; k += 2) { Blowfish_encipher(c, &datal, &datar); c->S[i][k] = datal; c->S[i][k + 1] = datar; } } } void Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes, const u_int8_t *key, u_int16_t keybytes) { u_int16_t i; u_int16_t j; u_int16_t k; u_int32_t temp; u_int32_t datal; u_int32_t datar; j = 0; for (i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; datal = 0x00000000; datar = 0x00000000; for (i = 0; i < BLF_N + 2; i += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->P[i] = datal; c->P[i + 1] = datar; } for (i = 0; i < 4; i++) { for (k = 0; k < 256; k += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->S[i][k] = datal; c->S[i][k + 1] = datar; } } } void blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len) { /* Initialize S-boxes and subkeys with Pi */ Blowfish_initstate(c); /* Transform S-boxes and subkeys with key */ Blowfish_expand0state(c, k, len); } void blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) { u_int32_t *d; u_int16_t i; d = data; for (i = 0; i < blocks; i++) { Blowfish_encipher(c, d, d + 1); d += 2; } } void blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) { u_int32_t *d; u_int16_t i; d = data; for (i = 0; i < blocks; i++) { Blowfish_decipher(c, d, d + 1); d += 2; } } void blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) { u_int32_t l, r; u_int32_t i; for (i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } } void blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) { u_int32_t l, r; u_int32_t i; for (i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } } void blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) { u_int32_t l, r; u_int32_t i, j; for (i = 0; i < len; i += 8) { for (j = 0; j < 8; j++) data[j] ^= iv[j]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; iv = data; data += 8; } } void blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) { u_int32_t l, r; u_int8_t *iv; u_int32_t i, j; iv = data + len - 16; data = data + len - 8; for (i = len - 8; i >= 8; i -= 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; for (j = 0; j < 8; j++) data[j] ^= iv[j]; iv -= 8; data -= 8; } l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; for (j = 0; j < 8; j++) data[j] ^= iva[j]; } #if 0 void report(u_int32_t data[], u_int16_t len) { u_int16_t i; for (i = 0; i < len; i += 2) printf("Block %0hd: %08lx %08lx.\n", i / 2, data[i], data[i + 1]); } void main(void) { blf_ctx c; char key[] = "AAAAA"; char key2[] = "abcdefghijklmnopqrstuvwxyz"; u_int32_t data[10]; u_int32_t data2[] = {0x424c4f57l, 0x46495348l}; u_int16_t i; /* First test */ for (i = 0; i < 10; i++) data[i] = i; blf_key(&c, (u_int8_t *) key, 5); blf_enc(&c, data, 5); blf_dec(&c, data, 1); blf_dec(&c, data + 2, 4); printf("Should read as 0 - 9.\n"); report(data, 10); /* Second test */ blf_key(&c, (u_int8_t *) key2, strlen(key2)); blf_enc(&c, data2, 1); printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); report(data2, 2); blf_dec(&c, data2, 1); report(data2, 2); } #endif #endif /* !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) */ openssh-7.2p2/openbsd-compat/bsd-asprintf.c010064400017500001750000000045411267006270000171310ustar00djmdjm/* * Copyright (c) 2004 Darren Tucker. * * Based originally on asprintf.c from OpenBSD: * Copyright (c) 1997 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef HAVE_VASPRINTF #include #include #include #ifndef VA_COPY # ifdef HAVE_VA_COPY # define VA_COPY(dest, src) va_copy(dest, src) # else # ifdef HAVE___VA_COPY # define VA_COPY(dest, src) __va_copy(dest, src) # else # define VA_COPY(dest, src) (dest) = (src) # endif # endif #endif #define INIT_SZ 128 int vasprintf(char **str, const char *fmt, va_list ap) { int ret = -1; va_list ap2; char *string, *newstr; size_t len; VA_COPY(ap2, ap); if ((string = malloc(INIT_SZ)) == NULL) goto fail; ret = vsnprintf(string, INIT_SZ, fmt, ap2); if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ *str = string; } else if (ret == INT_MAX || ret < 0) { /* Bad length */ free(string); goto fail; } else { /* bigger than initial, realloc allowing for nul */ len = (size_t)ret + 1; if ((newstr = realloc(string, len)) == NULL) { free(string); goto fail; } else { va_end(ap2); VA_COPY(ap2, ap); ret = vsnprintf(newstr, len, fmt, ap2); if (ret >= 0 && (size_t)ret < len) { *str = newstr; } else { /* failed with realloc'ed string, give up */ free(newstr); goto fail; } } } va_end(ap2); return (ret); fail: *str = NULL; errno = ENOMEM; va_end(ap2); return (-1); } #endif #ifndef HAVE_ASPRINTF int asprintf(char **str, const char *fmt, ...) { va_list ap; int ret; *str = NULL; va_start(ap, fmt); ret = vasprintf(str, fmt, ap); va_end(ap); return ret; } #endif openssh-7.2p2/openbsd-compat/bsd-closefrom.c010064400017500001750000000055321267006270000172750ustar00djmdjm/* * Copyright (c) 2004-2005 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef HAVE_CLOSEFROM #include #include #include #include #ifdef HAVE_FCNTL_H # include #endif #include #include #include #include #include #ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # ifdef HAVE_SYS_NDIR_H # include # endif # ifdef HAVE_SYS_DIR_H # include # endif # ifdef HAVE_NDIR_H # include # endif #endif #ifndef OPEN_MAX # define OPEN_MAX 256 #endif #if 0 __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; #endif /* lint */ /* * Close all file descriptors greater than or equal to lowfd. */ #ifdef HAVE_FCNTL_CLOSEM void closefrom(int lowfd) { (void) fcntl(lowfd, F_CLOSEM, 0); } #else void closefrom(int lowfd) { long fd, maxfd; #if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) char fdpath[PATH_MAX], *endp; struct dirent *dent; DIR *dirp; int len; /* Check for a /proc/$$/fd directory. */ len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { while ((dent = readdir(dirp)) != NULL) { fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) (void) close((int) fd); } (void) closedir(dirp); } else #endif { /* * Fall back on sysconf() or getdtablesize(). We avoid checking * resource limits since it is possible to open a file descriptor * and then drop the rlimit such that it is below the open fd. */ #ifdef HAVE_SYSCONF maxfd = sysconf(_SC_OPEN_MAX); #else maxfd = getdtablesize(); #endif /* HAVE_SYSCONF */ if (maxfd < 0) maxfd = OPEN_MAX; for (fd = lowfd; fd < maxfd; fd++) (void) close((int) fd); } } #endif /* !HAVE_FCNTL_CLOSEM */ #endif /* HAVE_CLOSEFROM */ openssh-7.2p2/openbsd-compat/bsd-cray.c010064400017500001750000000500501267006270000162350ustar00djmdjm/* * $Id: bsd-cray.c,v 1.17 2007/08/15 09:17:43 dtucker Exp $ * * bsd-cray.c * * Copyright (c) 2002, Cray Inc. (Wendy Palm ) * Significant portions provided by * Wayne Schroeder, SDSC * William Jones, UTexas * * 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. * * Created: Apr 22 16.34:00 2002 wp * * This file contains functions required for proper execution * on UNICOS systems. * */ #ifdef _UNICOS #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ssh.h" #include "includes.h" #include "sys/types.h" #ifndef HAVE_STRUCT_SOCKADDR_STORAGE # define _SS_MAXSIZE 128 /* Implementation specific max size */ # define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) # define ss_family ss_sa.sa_family #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ #ifndef IN6_IS_ADDR_LOOPBACK # define IN6_IS_ADDR_LOOPBACK(a) \ (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) #endif /* !IN6_IS_ADDR_LOOPBACK */ #ifndef AF_INET6 /* Define it to something that should never appear */ #define AF_INET6 AF_MAX #endif #include "log.h" #include "servconf.h" #include "bsd-cray.h" #define MAXACID 80 extern ServerOptions options; char cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ struct sysv sysv; /* system security structure */ struct usrv usrv; /* user security structure */ /* * Functions. */ void cray_retain_utmp(struct utmp *, int); void cray_delete_tmpdir(char *, int, uid_t); void cray_init_job(struct passwd *); void cray_set_tmpdir(struct utmp *); void cray_login_failure(char *, int); int cray_setup(uid_t, char *, const char *); int cray_access_denied(char *); void cray_login_failure(char *username, int errcode) { struct udb *ueptr; /* UDB pointer for username */ ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ struct jtab jtab; /* job table structure */ int jid = 0; /* job id */ if ((jid = getjtab(&jtab)) < 0) debug("cray_login_failure(): getjtab error"); getsysudb(); if ((ueptr = getudbnam(username)) == UDB_NULL) debug("cray_login_failure(): getudbname() returned NULL"); endudb(); memset(&fsent, '\0', sizeof(fsent)); fsent.revision = 0; fsent.uname = username; fsent.host = (char *)get_canonical_hostname(options.use_dns); fsent.ttyn = "sshd"; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = ueptr; fsent.jid = jid; fsent.errcode = errcode; fsent.pwdp = NULL; fsent.exitcode = 0; /* dont exit in ia_failure() */ fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an login failure. */ ia_failure(&fsent, &fret); } /* * Cray access denied */ int cray_access_denied(char *username) { struct udb *ueptr; /* UDB pointer for username */ int errcode; /* IA errorcode */ errcode = 0; getsysudb(); if ((ueptr = getudbnam(username)) == UDB_NULL) debug("cray_login_failure(): getudbname() returned NULL"); endudb(); if (ueptr != NULL && ueptr->ue_disabled) errcode = IA_DISABLED; if (errcode) cray_login_failure(username, errcode); return (errcode); } /* * record_failed_login: generic "login failed" interface function */ void record_failed_login(const char *user, const char *hostname, const char *ttyname) { cray_login_failure((char *)user, IA_UDBERR); } int cray_setup (uid_t uid, char *username, const char *command) { extern struct udb *getudb(); extern char *setlimits(); int err; /* error return */ time_t system_time; /* current system clock */ time_t expiration_time; /* password expiration time */ int maxattempts; /* maximum no. of failed login attempts */ int SecureSys; /* unicos security flag */ int minslevel = 0; /* system minimum security level */ int i, j; int valid_acct = -1; /* flag for reading valid acct */ char acct_name[MAXACID] = { "" }; /* used to read acct name */ struct jtab jtab; /* Job table struct */ struct udb ue; /* udb entry for logging-in user */ struct udb *up; /* pointer to UDB entry */ struct secstat secinfo; /* file security attributes */ struct servprov init_info; /* used for sesscntl() call */ int jid; /* job ID */ int pid; /* process ID */ char *sr; /* status return from setlimits() */ char *ttyn = NULL; /* ttyname or command name*/ char hostname[MAXHOSTNAMELEN]; /* passwd stuff for ia_user */ passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; ia_user_ret_t uret; /* stuff returned from ia_user */ ia_user_t usent; /* ia_user main structure */ int ia_rcode; /* ia_user return code */ ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ ia_success_t ssent; /* ia_success structure */ ia_success_ret_t sret; /* ia_success return stuff */ int ia_mlsrcode; /* ia_mlsuser return code */ int secstatrc; /* [f]secstat return code */ if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { getsysv(&sysv, sizeof(struct sysv)); minslevel = sysv.sy_minlvl; if (getusrv(&usrv) < 0) fatal("getusrv() failed, errno = %d", errno); } hostname[0] = '\0'; strlcpy(hostname, (char *)get_canonical_hostname(options.use_dns), MAXHOSTNAMELEN); /* * Fetch user's UDB entry. */ getsysudb(); if ((up = getudbnam(username)) == UDB_NULL) fatal("cannot fetch user's UDB entry"); /* * Prevent any possible fudging so perform a data * safety check and compare the supplied uid against * the udb's uid. */ if (up->ue_uid != uid) fatal("IA uid missmatch"); endudb(); if ((jid = getjtab(&jtab)) < 0) { debug("getjtab"); return(-1); } pid = getpid(); ttyn = ttyname(0); if (SecureSys) { if (ttyn != NULL) secstatrc = secstat(ttyn, &secinfo); else secstatrc = fsecstat(1, &secinfo); if (secstatrc == 0) debug("[f]secstat() successful"); else fatal("[f]secstat() error, rc = %d", secstatrc); } if ((ttyn == NULL) && ((char *)command != NULL)) ttyn = (char *)command; /* * Initialize all structures to call ia_user */ usent.revision = 0; usent.uname = username; usent.host = hostname; usent.ttyn = ttyn; usent.caller = IA_SSHD; usent.pswdlist = &pwdacm; usent.ueptr = &ue; usent.flags = IA_INTERACTIVE | IA_FFLAG; pwdacm.atype = IA_SECURID; pwdacm.pwdp = NULL; pwdacm.next = &pwdudb; pwdudb.atype = IA_UDB; pwdudb.pwdp = NULL; pwdudb.next = &pwddce; pwddce.atype = IA_DCE; pwddce.pwdp = NULL; pwddce.next = &pwddialup; pwddialup.atype = IA_DIALUP; pwddialup.pwdp = NULL; /* pwddialup.next = &pwdwal; */ pwddialup.next = NULL; pwdwal.atype = IA_WAL; pwdwal.pwdp = NULL; pwdwal.next = NULL; uret.revision = 0; uret.pswd = NULL; uret.normal = 0; ia_rcode = ia_user(&usent, &uret); switch (ia_rcode) { /* * These are acceptable return codes from ia_user() */ case IA_UDBWEEK: /* Password Expires in 1 week */ expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; printf ("WARNING - your current password will expire %s\n", ctime((const time_t *)&expiration_time)); break; case IA_UDBEXPIRED: if (ttyname(0) != NULL) { /* Force a password change */ printf("Your password has expired; Choose a new one.\n"); execl("/bin/passwd", "passwd", username, 0); exit(9); } break; case IA_NORMAL: /* Normal Return Code */ break; case IA_BACKDOOR: /* XXX: can we memset it to zero here so save some of this */ strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); ue.ue_passwd[0] = '\0'; ue.ue_age[0] = '\0'; ue.ue_comment[0] = '\0'; ue.ue_loghost[0] = '\0'; ue.ue_logline[0] = '\0'; ue.ue_uid = -1; ue.ue_nice[UDBRC_INTER] = 0; for (i = 0; i < MAXVIDS; i++) ue.ue_gids[i] = 0; ue.ue_logfails = 0; ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; ue.ue_defcomps = 0; ue.ue_comparts = 0; ue.ue_permits = 0; ue.ue_trap = 0; ue.ue_disabled = 0; ue.ue_logtime = 0; break; case IA_CONSOLE: /* Superuser not from Console */ case IA_TRUSTED: /* Trusted user */ if (options.permit_root_login > PERMIT_NO) break; /* Accept root login */ default: /* * These are failed return codes from ia_user() */ switch (ia_rcode) { case IA_BADAUTH: printf("Bad authorization, access denied.\n"); break; case IA_DISABLED: printf("Your login has been disabled. Contact the system "); printf("administrator for assistance.\n"); break; case IA_GETSYSV: printf("getsysv() failed - errno = %d\n", errno); break; case IA_MAXLOGS: printf("Maximum number of failed login attempts exceeded.\n"); printf("Access denied.\n"); break; case IA_UDBPWDNULL: if (SecureSys) printf("NULL Password not allowed on MLS systems.\n"); break; default: break; } /* * Authentication failed. */ printf("sshd: Login incorrect, (0%o)\n", ia_rcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_rcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent, &fret); exit(1); } ia_mlsrcode = IA_NORMAL; if (SecureSys) { debug("calling ia_mlsuser()"); ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); } if (ia_mlsrcode != IA_NORMAL) { printf("sshd: Login incorrect, (0%o)\n", ia_mlsrcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_mlsrcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent,&fret); exit(1); } /* Provide login status information */ if (options.print_lastlog && ue.ue_logtime != 0) { printf("Last successful login was : %.*s ", 19, (char *)ctime(&ue.ue_logtime)); if (*ue.ue_loghost != '\0') { printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost); } else { printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline); } if (SecureSys && (ue.ue_logfails != 0)) { printf(" followed by %d failed attempts\n", ue.ue_logfails); } } /* * Call ia_success to process successful I/A. */ ssent.revision = 0; ssent.uname = username; ssent.host = hostname; ssent.ttyn = ttyn; ssent.caller = IA_SSHD; ssent.flags = IA_INTERACTIVE; ssent.ueptr = &ue; ssent.jid = jid; ssent.errcode = ia_rcode; ssent.us = NULL; ssent.time = 1; /* Set ue_logtime */ sret.revision = 0; sret.normal = 0; ia_success(&ssent, &sret); /* * Query for account, iff > 1 valid acid & askacid permbit */ if (((ue.ue_permbits & PERMBITS_ACCTID) || (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && ue.ue_permbits & PERMBITS_ASKACID) { if (ttyname(0) != NULL) { debug("cray_setup: ttyname true case, %.100s", ttyname); while (valid_acct == -1) { printf("Account (? for available accounts)" " [%s]: ", acid2nam(ue.ue_acids[0])); fgets(acct_name, MAXACID, stdin); switch (acct_name[0]) { case EOF: exit(0); break; case '\0': valid_acct = ue.ue_acids[0]; strlcpy(acct_name, acid2nam(valid_acct), MAXACID); break; case '?': /* Print the list 3 wide */ for (i = 0, j = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) { printf("\n"); break; } if (++j == 4) { j = 1; printf("\n"); } printf(" %s", acid2nam(ue.ue_acids[i])); } if (ue.ue_permbits & PERMBITS_ACCTID) { printf("\"acctid\" permbit also allows" " you to select any valid " "account name.\n"); } printf("\n"); break; default: valid_acct = nam2acid(acct_name); if (valid_acct == -1) printf( "Account id not found for" " account name \"%s\"\n\n", acct_name); break; } /* * If an account was given, search the user's * acids array to verify they can use this account. */ if ((valid_acct != -1) && !(ue.ue_permbits & PERMBITS_ACCTID)) { for (i = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) break; if (valid_acct == ue.ue_acids[i]) break; } if (i == MAXVIDS || ue.ue_acids[i] == -1) { fprintf(stderr, "Cannot set" " account name to " "\"%s\", permission " "denied\n\n", acct_name); valid_acct = -1; } } } } else { /* * The client isn't connected to a terminal and can't * respond to an acid prompt. Use default acid. */ debug("cray_setup: ttyname false case, %.100s", ttyname); valid_acct = ue.ue_acids[0]; } } else { /* * The user doesn't have the askacid permbit set or * only has one valid account to use. */ valid_acct = ue.ue_acids[0]; } if (acctid(0, valid_acct) < 0) { printf ("Bad account id: %d\n", valid_acct); exit(1); } /* * Now set shares, quotas, limits, including CPU time for the * (interactive) job and process, and set up permissions * (for chown etc), etc. */ if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); exit(1); } sr = setlimits(username, C_PROC, pid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } sr = setlimits(username, C_JOB, jid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } /* * Place the service provider information into * the session table (Unicos) or job table (Unicos/mk). * There exist double defines for the job/session table in * unicos/mk (jtab.h) so no need for a compile time switch. */ memset(&init_info, '\0', sizeof(init_info)); init_info.s_sessinit.si_id = URM_SPT_LOGIN; init_info.s_sessinit.si_pid = getpid(); init_info.s_sessinit.si_sid = jid; sesscntl(0, S_SETSERVPO, (int)&init_info); /* * Set user and controlling tty security attributes. */ if (SecureSys) { if (setusrv(&usrv) == -1) { debug("setusrv() failed, errno = %d",errno); exit(1); } } return (0); } /* * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk * can have pal privileges that sshd can inherit which * could allow a user to su to root with out a password. * This subroutine clears all privileges. */ void drop_cray_privs() { #if defined(_SC_CRAY_PRIV_SU) priv_proc_t *privstate; int result; extern int priv_set_proc(); extern priv_proc_t *priv_init_proc(); /* * If ether of theses two flags are not set * then don't allow this version of ssh to run. */ if (!sysconf(_SC_CRAY_PRIV_SU)) fatal("Not PRIV_SU system."); if (!sysconf(_SC_CRAY_POSIX_PRIV)) fatal("Not POSIX_PRIV."); debug("Setting MLS labels.");; if (sysconf(_SC_CRAY_SECURE_MAC)) { usrv.sv_minlvl = SYSLOW; usrv.sv_actlvl = SYSHIGH; usrv.sv_maxlvl = SYSHIGH; } else { usrv.sv_minlvl = sysv.sy_minlvl; usrv.sv_actlvl = sysv.sy_minlvl; usrv.sv_maxlvl = sysv.sy_maxlvl; } usrv.sv_actcmp = 0; usrv.sv_valcmp = sysv.sy_valcmp; usrv.sv_intcat = TFM_SYSTEM; usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); if (setusrv(&usrv) < 0) { fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, strerror(errno)); } if ((privstate = priv_init_proc()) != NULL) { result = priv_set_proc(privstate); if (result != 0 ) { fatal("%s(%d): priv_set_proc(): %s", __FILE__, __LINE__, strerror(errno)); } priv_free_proc(privstate); } debug ("Privileges should be cleared..."); #else /* XXX: do this differently */ # error Cray systems must be run with _SC_CRAY_PRIV_SU on! #endif } /* * Retain utmp/wtmp information - used by cray accounting. */ void cray_retain_utmp(struct utmp *ut, int pid) { int fd; struct utmp utmp; if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { /* XXX use atomicio */ while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { if (pid == utmp.ut_pid) { ut->ut_jid = utmp.ut_jid; strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); break; } } close(fd); } else fatal("Unable to open utmp file"); } /* * tmpdir support. */ /* * find and delete jobs tmpdir. */ void cray_delete_tmpdir(char *login, int jid, uid_t uid) { static char jtmp[TPATHSIZ]; struct stat statbuf; int child, c, wstat; for (c = 'a'; c <= 'z'; c++) { snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) break; } if (c > 'z') return; if ((child = fork()) == 0) { execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); } while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) ; } /* * Remove tmpdir on job termination. */ void cray_job_termination_handler(int sig) { int jid; char *login = NULL; struct jtab jtab; if ((jid = waitjob(&jtab)) == -1 || (login = uid2nam(jtab.j_uid)) == NULL) return; cray_delete_tmpdir(login, jid, jtab.j_uid); } /* * Set job id and create tmpdir directory. */ void cray_init_job(struct passwd *pw) { int jid; int c; jid = setjob(pw->pw_uid, WJSIGNAL); if (jid < 0) fatal("System call setjob failure"); for (c = 'a'; c <= 'z'; c++) { snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); if (mkdir(cray_tmpdir, JTMPMODE) != 0) continue; if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { rmdir(cray_tmpdir); continue; } break; } if (c > 'z') cray_tmpdir[0] = '\0'; } void cray_set_tmpdir(struct utmp *ut) { int jid; struct jtab jbuf; if ((jid = getjtab(&jbuf)) < 0) return; /* * Set jid and tmpdir in utmp record. */ ut->ut_jid = jid; strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); } #endif /* UNICOS */ #ifdef _UNICOSMP #include /* * Set job id and create tmpdir directory. */ void cray_init_job(struct passwd *pw) { initrm_silent(pw->pw_uid); return; } #endif /* _UNICOSMP */ openssh-7.2p2/openbsd-compat/bsd-cray.h010064400017500001750000000041311267006270000162410ustar00djmdjm/* $Id: bsd-cray.h,v 1.12 2005/02/02 06:10:11 dtucker Exp $ */ /* * Copyright (c) 2002, Cray Inc. (Wendy Palm ) * Significant portions provided by * Wayne Schroeder, SDSC * William Jones, UTexas * * 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. * * Created: Apr 22 16.34:00 2002 wp * * This file contains functions required for proper execution * on UNICOS systems. * */ #ifndef _BSD_CRAY_H #define _BSD_CRAY_H #ifdef _UNICOS void cray_init_job(struct passwd *); void cray_job_termination_handler(int); void cray_login_failure(char *, int ); int cray_access_denied(char *); extern char cray_tmpdir[]; #define CUSTOM_FAILED_LOGIN 1 #ifndef IA_SSHD # define IA_SSHD IA_LOGIN #endif #ifndef MAXHOSTNAMELEN # define MAXHOSTNAMELEN 64 #endif #ifndef _CRAYT3E # define TIOCGPGRP (tIOC|20) #endif #endif /* UNICOS */ #endif /* _BSD_CRAY_H */ openssh-7.2p2/openbsd-compat/bsd-cygwin_util.c010064400017500001750000000062111267006270000176340ustar00djmdjm/* * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen * * 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. * * Created: Sat Sep 02 12:17:00 2000 cv * * This file contains functions for forcing opened file descriptors to * binary mode on Windows systems. */ #define NO_BINARY_OPEN /* Avoid redefining open to binary_open for this file */ #include "includes.h" #ifdef HAVE_CYGWIN #include #include #include #include #include "xmalloc.h" int binary_open(const char *filename, int flags, ...) { va_list ap; mode_t mode; va_start(ap, flags); mode = va_arg(ap, mode_t); va_end(ap); return (open(filename, flags | O_BINARY, mode)); } int check_ntsec(const char *filename) { return (pathconf(filename, _PC_POSIX_PERMISSIONS)); } const char * cygwin_ssh_privsep_user() { static char cyg_privsep_user[DNLEN + UNLEN + 2]; if (!cyg_privsep_user[0]) { #ifdef CW_CYGNAME_FROM_WINNAME if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user, sizeof cyg_privsep_user) != 0) #endif strlcpy(cyg_privsep_user, "sshd", sizeof(cyg_privsep_user)); } return cyg_privsep_user; } #define NL(x) x, (sizeof (x) - 1) #define WENV_SIZ (sizeof (wenv_arr) / sizeof (wenv_arr[0])) static struct wenv { const char *name; size_t namelen; } wenv_arr[] = { { NL("ALLUSERSPROFILE=") }, { NL("COMPUTERNAME=") }, { NL("COMSPEC=") }, { NL("CYGWIN=") }, { NL("OS=") }, { NL("PATH=") }, { NL("PATHEXT=") }, { NL("PROGRAMFILES=") }, { NL("SYSTEMDRIVE=") }, { NL("SYSTEMROOT=") }, { NL("WINDIR=") } }; char ** fetch_windows_environment(void) { char **e, **p; unsigned int i, idx = 0; p = xcalloc(WENV_SIZ + 1, sizeof(char *)); for (e = environ; *e != NULL; ++e) { for (i = 0; i < WENV_SIZ; ++i) { if (!strncmp(*e, wenv_arr[i].name, wenv_arr[i].namelen)) p[idx++] = *e; } } p[idx] = NULL; return p; } void free_windows_environment(char **p) { free(p); } #endif /* HAVE_CYGWIN */ openssh-7.2p2/openbsd-compat/bsd-cygwin_util.h010064400017500001750000000046451267006270000176520ustar00djmdjm/* $Id: bsd-cygwin_util.h,v 1.18 2014/05/27 04:34:43 djm Exp $ */ /* * Copyright (c) 2000, 2001, 2011, 2013 Corinna Vinschen * * 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. * * Created: Sat Sep 02 12:17:00 2000 cv * * This file contains functions for forcing opened file descriptors to * binary mode on Windows systems. */ #ifndef _BSD_CYGWIN_UTIL_H #define _BSD_CYGWIN_UTIL_H #ifdef HAVE_CYGWIN #undef ERROR /* Avoid including windows headers. */ typedef void *HANDLE; #define INVALID_HANDLE_VALUE ((HANDLE) -1) #define DNLEN 16 #define UNLEN 256 /* Cygwin functions for which declarations are only available when including windows headers, so we have to define them here explicitely. */ extern HANDLE cygwin_logon_user (const struct passwd *, const char *); extern void cygwin_set_impersonation_token (const HANDLE); #include #include #define CYGWIN_SSH_PRIVSEP_USER (cygwin_ssh_privsep_user()) const char *cygwin_ssh_privsep_user(); int binary_open(const char *, int , ...); int check_ntsec(const char *); char **fetch_windows_environment(void); void free_windows_environment(char **); #ifndef NO_BINARY_OPEN #define open binary_open #endif #endif /* HAVE_CYGWIN */ #endif /* _BSD_CYGWIN_UTIL_H */ openssh-7.2p2/openbsd-compat/bsd-getpeereid.c010064400017500001750000000032651267006270000174220ustar00djmdjm/* * Copyright (c) 2002,2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if !defined(HAVE_GETPEEREID) #include #include #include #if defined(SO_PEERCRED) int getpeereid(int s, uid_t *euid, gid_t *gid) { struct ucred cred; socklen_t len = sizeof(cred); if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) return (-1); *euid = cred.uid; *gid = cred.gid; return (0); } #elif defined(HAVE_GETPEERUCRED) #ifdef HAVE_UCRED_H # include #endif int getpeereid(int s, uid_t *euid, gid_t *gid) { ucred_t *ucred = NULL; if (getpeerucred(s, &ucred) == -1) return (-1); if ((*euid = ucred_geteuid(ucred)) == -1) return (-1); if ((*gid = ucred_getrgid(ucred)) == -1) return (-1); ucred_free(ucred); return (0); } #else int getpeereid(int s, uid_t *euid, gid_t *gid) { *euid = geteuid(); *gid = getgid(); return (0); } #endif /* defined(SO_PEERCRED) */ #endif /* !defined(HAVE_GETPEEREID) */ openssh-7.2p2/openbsd-compat/bsd-misc.c010064400017500001750000000130011267006270000162250ustar00djmdjm /* * Copyright (c) 1999-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #ifndef HAVE___PROGNAME char *__progname; #endif /* * NB. duplicate __progname in case it is an alias for argv[0] * Otherwise it may get clobbered by setproctitle() */ char *ssh_get_progname(char *argv0) { char *p, *q; #ifdef HAVE___PROGNAME extern char *__progname; p = __progname; #else if (argv0 == NULL) return ("unknown"); /* XXX */ p = strrchr(argv0, '/'); if (p == NULL) p = argv0; else p++; #endif if ((q = strdup(p)) == NULL) { perror("strdup"); exit(1); } return q; } #ifndef HAVE_SETLOGIN int setlogin(const char *name) { return (0); } #endif /* !HAVE_SETLOGIN */ #ifndef HAVE_INNETGR int innetgr(const char *netgroup, const char *host, const char *user, const char *domain) { return (0); } #endif /* HAVE_INNETGR */ #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) int seteuid(uid_t euid) { return (setreuid(-1, euid)); } #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) int setegid(uid_t egid) { return(setresgid(-1, egid, -1)); } #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) const char *strerror(int e) { extern int sys_nerr; extern char *sys_errlist[]; if ((e >= 0) && (e < sys_nerr)) return (sys_errlist[e]); return ("unlisted error"); } #endif #ifndef HAVE_UTIMES int utimes(char *filename, struct timeval *tvp) { struct utimbuf ub; ub.actime = tvp[0].tv_sec; ub.modtime = tvp[1].tv_sec; return (utime(filename, &ub)); } #endif #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { int fd, ret, saverrno; fd = open(path, O_WRONLY); if (fd < 0) return (-1); ret = ftruncate(fd, length); saverrno = errno; close(fd); if (ret == -1) errno = saverrno; return(ret); } #endif /* HAVE_TRUNCATE */ #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) int nanosleep(const struct timespec *req, struct timespec *rem) { int rc, saverrno; extern int errno; struct timeval tstart, tstop, tremain, time2wait; TIMESPEC_TO_TIMEVAL(&time2wait, req) (void) gettimeofday(&tstart, NULL); rc = select(0, NULL, NULL, NULL, &time2wait); if (rc == -1) { saverrno = errno; (void) gettimeofday (&tstop, NULL); errno = saverrno; tremain.tv_sec = time2wait.tv_sec - (tstop.tv_sec - tstart.tv_sec); tremain.tv_usec = time2wait.tv_usec - (tstop.tv_usec - tstart.tv_usec); tremain.tv_sec += tremain.tv_usec / 1000000L; tremain.tv_usec %= 1000000L; } else { tremain.tv_sec = 0; tremain.tv_usec = 0; } if (rem != NULL) TIMEVAL_TO_TIMESPEC(&tremain, rem) return(rc); } #endif #if !defined(HAVE_USLEEP) int usleep(unsigned int useconds) { struct timespec ts; ts.tv_sec = useconds / 1000000; ts.tv_nsec = (useconds % 1000000) * 1000; return nanosleep(&ts, NULL); } #endif #ifndef HAVE_TCGETPGRP pid_t tcgetpgrp(int fd) { int ctty_pgrp; if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) return(-1); else return(ctty_pgrp); } #endif /* HAVE_TCGETPGRP */ #ifndef HAVE_TCSENDBREAK int tcsendbreak(int fd, int duration) { # if defined(TIOCSBRK) && defined(TIOCCBRK) struct timeval sleepytime; sleepytime.tv_sec = 0; sleepytime.tv_usec = 400000; if (ioctl(fd, TIOCSBRK, 0) == -1) return (-1); (void)select(0, 0, 0, 0, &sleepytime); if (ioctl(fd, TIOCCBRK, 0) == -1) return (-1); return (0); # else return -1; # endif } #endif /* HAVE_TCSENDBREAK */ mysig_t mysignal(int sig, mysig_t act) { #ifdef HAVE_SIGACTION struct sigaction sa, osa; if (sigaction(sig, NULL, &osa) == -1) return (mysig_t) -1; if (osa.sa_handler != act) { memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; #ifdef SA_INTERRUPT if (sig == SIGALRM) sa.sa_flags |= SA_INTERRUPT; #endif sa.sa_handler = act; if (sigaction(sig, &sa, NULL) == -1) return (mysig_t) -1; } return (osa.sa_handler); #else #undef signal return (signal(sig, act)); #endif } #ifndef HAVE_STRDUP char * strdup(const char *str) { size_t len; char *cp; len = strlen(str) + 1; cp = malloc(len); if (cp != NULL) return(memcpy(cp, str, len)); return NULL; } #endif #ifndef HAVE_ISBLANK int isblank(int c) { return (c == ' ' || c == '\t'); } #endif #ifndef HAVE_GETPGID pid_t getpgid(pid_t pid) { #if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) return getpgrp(pid); #elif defined(HAVE_GETPGRP) if (pid == 0) return getpgrp(); #endif errno = ESRCH; return -1; } #endif #ifndef HAVE_PLEDGE int pledge(const char *promises, const char *paths[]) { return 0; } #endif openssh-7.2p2/openbsd-compat/bsd-misc.h010064400017500001750000000061101267006270000162350ustar00djmdjm/* $Id: bsd-misc.h,v 1.25 2013/08/04 11:48:41 dtucker Exp $ */ /* * Copyright (c) 1999-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _BSD_MISC_H #define _BSD_MISC_H #include "includes.h" char *ssh_get_progname(char *); #ifndef HAVE_SETSID #define setsid() setpgrp(0, getpid()) #endif /* !HAVE_SETSID */ #ifndef HAVE_SETENV int setenv(const char *, const char *, int); #endif /* !HAVE_SETENV */ #ifndef HAVE_SETLOGIN int setlogin(const char *); #endif /* !HAVE_SETLOGIN */ #ifndef HAVE_INNETGR int innetgr(const char *, const char *, const char *, const char *); #endif /* HAVE_INNETGR */ #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) int seteuid(uid_t); #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) int setegid(uid_t); #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) const char *strerror(int); #endif #if !defined(HAVE_SETLINEBUF) #define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0)) #endif #ifndef HAVE_UTIMES #ifndef HAVE_STRUCT_TIMEVAL struct timeval { long tv_sec; long tv_usec; } #endif /* HAVE_STRUCT_TIMEVAL */ int utimes(char *, struct timeval *); #endif /* HAVE_UTIMES */ #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) #ifndef HAVE_STRUCT_TIMESPEC struct timespec { time_t tv_sec; long tv_nsec; }; #endif int nanosleep(const struct timespec *, struct timespec *); #endif #ifndef HAVE_USLEEP int usleep(unsigned int useconds); #endif #ifndef HAVE_TCGETPGRP pid_t tcgetpgrp(int); #endif #ifndef HAVE_TCSENDBREAK int tcsendbreak(int, int); #endif #ifndef HAVE_UNSETENV int unsetenv(const char *); #endif /* wrapper for signal interface */ typedef void (*mysig_t)(int); mysig_t mysignal(int sig, mysig_t act); #define signal(a,b) mysignal(a,b) #ifndef HAVE_ISBLANK int isblank(int); #endif #ifndef HAVE_GETPGID pid_t getpgid(pid_t); #endif #ifndef HAVE_ENDGRENT # define endgrent() do { } while(0) #endif #ifndef HAVE_KRB5_GET_ERROR_MESSAGE # define krb5_get_error_message krb5_get_err_text #endif #ifndef HAVE_KRB5_FREE_ERROR_MESSAGE # define krb5_free_error_message(a,b) do { } while(0) #endif #ifndef HAVE_PLEDGE int pledge(const char *promises, const char *paths[]); #endif #endif /* _BSD_MISC_H */ openssh-7.2p2/openbsd-compat/bsd-nextstep.c010064400017500001750000000050011267006270000171450ustar00djmdjm/* * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 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_NEXT #include #include #include "bsd-nextstep.h" pid_t posix_wait(int *status) { union wait statusp; pid_t wait_pid; #undef wait /* Use NeXT's wait() function */ wait_pid = wait(&statusp); if (status) *status = (int) statusp.w_status; return (wait_pid); } int tcgetattr(int fd, struct termios *t) { return (ioctl(fd, TIOCGETA, t)); } int tcsetattr(int fd, int opt, const struct termios *t) { struct termios localterm; if (opt & TCSASOFT) { localterm = *t; localterm.c_cflag |= CIGNORE; t = &localterm; } switch (opt & ~TCSASOFT) { case TCSANOW: return (ioctl(fd, TIOCSETA, t)); case TCSADRAIN: return (ioctl(fd, TIOCSETAW, t)); case TCSAFLUSH: return (ioctl(fd, TIOCSETAF, t)); default: errno = EINVAL; return (-1); } } int tcsetpgrp(int fd, pid_t pgrp) { return (ioctl(fd, TIOCSPGRP, &pgrp)); } speed_t cfgetospeed(const struct termios *t) { return (t->c_ospeed); } speed_t cfgetispeed(const struct termios *t) { return (t->c_ispeed); } int cfsetospeed(struct termios *t,int speed) { t->c_ospeed = speed; return (0); } int cfsetispeed(struct termios *t, int speed) { t->c_ispeed = speed; return (0); } #endif /* HAVE_NEXT */ openssh-7.2p2/openbsd-compat/bsd-nextstep.h010064400017500001750000000044471267006270000171670ustar00djmdjm/* $Id: bsd-nextstep.h,v 1.9 2003/08/29 16:59:52 mouring Exp $ */ /* * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 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 _NEXT_POSIX_H #define _NEXT_POSIX_H #ifdef HAVE_NEXT #include /* NGROUPS_MAX is behind -lposix. Use the BSD version which is NGROUPS */ #undef NGROUPS_MAX #define NGROUPS_MAX NGROUPS /* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */ #define dirent direct /* Swap out NeXT's BSD wait() for a more POSIX complient one */ pid_t posix_wait(int *); #define wait(a) posix_wait(a) /* #ifdef wrapped functions that need defining for clean compiling */ pid_t getppid(void); void vhangup(void); int innetgr(const char *, const char *, const char *, const char *); /* TERMCAP */ int tcgetattr(int, struct termios *); int tcsetattr(int, int, const struct termios *); int tcsetpgrp(int, pid_t); speed_t cfgetospeed(const struct termios *); speed_t cfgetispeed(const struct termios *); int cfsetospeed(struct termios *, int); int cfsetispeed(struct termios *, int); #endif /* HAVE_NEXT */ #endif /* _NEXT_POSIX_H */ openssh-7.2p2/openbsd-compat/bsd-poll.c010064400017500001750000000057431267006270000162560ustar00djmdjm/* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */ /* * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if !defined(HAVE_POLL) #include #include #ifdef HAVE_SYS_SELECT_H # include #endif #include #include #include #include "bsd-poll.h" /* * A minimal implementation of poll(2), built on top of select(2). * * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT * and POLLERR flags in revents. * * Supports pfd.fd = -1 meaning "unused" although it's not standard. */ int poll(struct pollfd *fds, nfds_t nfds, int timeout) { nfds_t i; int saved_errno, ret, fd, maxfd = 0; fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; size_t nmemb; struct timeval tv, *tvp = NULL; for (i = 0; i < nfds; i++) { fd = fds[i].fd; if (fd >= FD_SETSIZE) { errno = EINVAL; return -1; } maxfd = MAX(maxfd, fd); } nmemb = howmany(maxfd + 1 , NFDBITS); if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { saved_errno = ENOMEM; ret = -1; goto out; } /* populate event bit vectors for the events we're interested in */ for (i = 0; i < nfds; i++) { fd = fds[i].fd; if (fd == -1) continue; if (fds[i].events & POLLIN) { FD_SET(fd, readfds); FD_SET(fd, exceptfds); } if (fds[i].events & POLLOUT) { FD_SET(fd, writefds); FD_SET(fd, exceptfds); } } /* poll timeout is msec, select is timeval (sec + usec) */ if (timeout >= 0) { tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; tvp = &tv; } ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); saved_errno = errno; /* scan through select results and set poll() flags */ for (i = 0; i < nfds; i++) { fd = fds[i].fd; fds[i].revents = 0; if (fd == -1) continue; if (FD_ISSET(fd, readfds)) { fds[i].revents |= POLLIN; } if (FD_ISSET(fd, writefds)) { fds[i].revents |= POLLOUT; } if (FD_ISSET(fd, exceptfds)) { fds[i].revents |= POLLERR; } } out: free(readfds); free(writefds); free(exceptfds); if (ret == -1) errno = saved_errno; return ret; } #endif openssh-7.2p2/openbsd-compat/bsd-openpty.c010064400017500001750000000127461267006270000170070ustar00djmdjm/* * Please note: this implementation of openpty() is far from complete. * it is just enough for portable OpenSSH's needs. */ /* * Copyright (c) 2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Allocating a pseudo-terminal, and making it the controlling tty. * * 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" #if !defined(HAVE_OPENPTY) #include #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_UTIL_H # include #endif /* HAVE_UTIL_H */ #ifdef HAVE_PTY_H # include #endif #if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) # include #endif #include #include #include #ifndef O_NOCTTY #define O_NOCTTY 0 #endif int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { #if defined(HAVE__GETPTY) /* * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more * pty's automagically when needed */ char *slave; if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL) return (-1); /* Open the slave side. */ if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) { close(*amaster); return (-1); } return (0); #elif defined(HAVE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) */ int ptm; char *pts; mysig_t old_signal; if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) return (-1); /* XXX: need to close ptm on error? */ old_signal = signal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) return (-1); signal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) return (-1); if ((pts = ptsname(ptm)) == NULL) return (-1); *amaster = ptm; /* Open the slave side. */ if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) { close(*amaster); return (-1); } /* * Try to push the appropriate streams modules, as described * in Solaris pts(7). */ ioctl(*aslave, I_PUSH, "ptem"); ioctl(*aslave, I_PUSH, "ldterm"); # ifndef __hpux ioctl(*aslave, I_PUSH, "ttcompat"); # endif /* __hpux */ return (0); #elif defined(HAVE_DEV_PTS_AND_PTC) /* AIX-style pty code. */ const char *ttname; if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1) return (-1); if ((ttname = ttyname(*amaster)) == NULL) return (-1); if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) { close(*amaster); return (-1); } return (0); #elif defined(_UNICOS) char ptbuf[64], ttbuf[64]; int i; int highpty; highpty = 128; #ifdef _SC_CRAY_NPTY if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1) highpty = 128; #endif /* _SC_CRAY_NPTY */ for (i = 0; i < highpty; i++) { snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i); snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i); if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1) continue; /* Open the slave side. */ if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) { close(*amaster); return (-1); } return (0); } return (-1); #else /* BSD-style pty code. */ char ptbuf[64], ttbuf[64]; int i; const char *ptymajors = "pqrstuvwxyzabcdefghijklmno" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; struct termios tio; for (i = 0; i < num_ptys; i++) { snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) { /* Try SCO style naming */ snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i); snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i); if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) continue; } /* Open the slave side. */ if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) { close(*amaster); return (-1); } /* set tty modes to a sane state for broken clients */ if (tcgetattr(*amaster, &tio) != -1) { tio.c_lflag |= (ECHO | ISIG | ICANON); tio.c_oflag |= (OPOST | ONLCR); tio.c_iflag |= ICRNL; tcsetattr(*amaster, TCSANOW, &tio); } return (0); } return (-1); #endif } #endif /* !defined(HAVE_OPENPTY) */ openssh-7.2p2/openbsd-compat/bsd-poll.h010064400017500001750000000041011267006270000162460ustar00djmdjm/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert Exp $ */ /* * Copyright (c) 1996 Theo de Raadt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* OPENBSD ORIGINAL: sys/sys/poll.h */ #if !defined(HAVE_POLL) && !defined(HAVE_POLL_H) #ifndef _COMPAT_POLL_H_ #define _COMPAT_POLL_H_ typedef struct pollfd { int fd; short events; short revents; } pollfd_t; typedef unsigned int nfds_t; #define POLLIN 0x0001 #define POLLOUT 0x0004 #define POLLERR 0x0008 #define POLLHUP 0x0010 #define POLLNVAL 0x0020 #if 0 /* the following are currently not implemented */ #define POLLPRI 0x0002 #define POLLRDNORM 0x0040 #define POLLNORM POLLRDNORM #define POLLWRNORM POLLOUT #define POLLRDBAND 0x0080 #define POLLWRBAND 0x0100 #endif #define INFTIM (-1) /* not standard */ int poll(struct pollfd *, nfds_t, int); #endif /* !_COMPAT_POLL_H_ */ #endif /* !HAVE_POLL_H */ openssh-7.2p2/openbsd-compat/bsd-setres_id.c010064400017500001750000000046361267006270000172710ustar00djmdjm/* $Id: bsd-setres_id.c,v 1.2 2013/12/07 21:23:09 djm Exp $ */ /* * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #include #include #include #include "log.h" #if !defined(HAVE_SETRESGID) || defined(BROKEN_SETRESGID) int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { int ret = 0, saved_errno; if (rgid != sgid) { errno = ENOSYS; return -1; } #if defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) if (setregid(rgid, egid) < 0) { saved_errno = errno; error("setregid %u: %.100s", rgid, strerror(errno)); errno = saved_errno; ret = -1; } #else if (setegid(egid) < 0) { saved_errno = errno; error("setegid %u: %.100s", (u_int)egid, strerror(errno)); errno = saved_errno; ret = -1; } if (setgid(rgid) < 0) { saved_errno = errno; error("setgid %u: %.100s", rgid, strerror(errno)); errno = saved_errno; ret = -1; } #endif return ret; } #endif #if !defined(HAVE_SETRESUID) || defined(BROKEN_SETRESUID) int setresuid(uid_t ruid, uid_t euid, uid_t suid) { int ret = 0, saved_errno; if (ruid != suid) { errno = ENOSYS; return -1; } #if defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) if (setreuid(ruid, euid) < 0) { saved_errno = errno; error("setreuid %u: %.100s", ruid, strerror(errno)); errno = saved_errno; ret = -1; } #else # ifndef SETEUID_BREAKS_SETUID if (seteuid(euid) < 0) { saved_errno = errno; error("seteuid %u: %.100s", euid, strerror(errno)); errno = saved_errno; ret = -1; } # endif if (setuid(ruid) < 0) { saved_errno = errno; error("setuid %u: %.100s", ruid, strerror(errno)); errno = saved_errno; ret = -1; } #endif return ret; } #endif openssh-7.2p2/openbsd-compat/bsd-setres_id.h010064400017500001750000000017461267006270000172750ustar00djmdjm/* $Id: bsd-setres_id.h,v 1.1 2012/11/05 06:04:37 dtucker Exp $ */ /* * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef HAVE_SETRESGID int setresgid(gid_t, gid_t, gid_t); #endif #ifndef HAVE_SETRESUID int setresuid(uid_t, uid_t, uid_t); #endif openssh-7.2p2/openbsd-compat/bsd-snprintf.c010064400017500001750000000515111267006270000171450ustar00djmdjm/* * 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 */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formated the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Andrew Tridgell (tridge@samba.org) Oct 1998 * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * * tridge@samba.org, idra@samba.org, April 2001 * got rid of fcvt code (twas buggy and made testing harder) * added C99 semantics * * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 * actually print args for %g and %e * * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 * Since includes.h isn't included here, VA_COPY has to be defined here. I don't * see any include file that is guaranteed to be here, so I'm defining it * locally. Fixes AIX and Solaris builds. * * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 * put the ifdef for HAVE_VA_COPY in one place rather than in lots of * functions * * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 * Fix usage of va_list passed as an arg. Use __va_copy before using it * when it exists. * * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 * Fix incorrect zpadlen handling in fmtfp. * Thanks to Ollie Oldham for spotting it. * few mods to make it easier to compile the tests. * addedd the "Ollie" test to the floating point ones. * * Martin Pool (mbp@samba.org) April 2003 * Remove NO_CONFIG_H so that the test case can be built within a source * tree with less trouble. * Remove unnecessary SAFE_FREE() definition. * * Martin Pool (mbp@samba.org) May 2003 * Put in a prototype for dummy_snprintf() to quiet compiler warnings. * * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even * if the C library has some snprintf functions already. * * Damien Miller (djm@mindrot.org) Jan 2007 * Fix integer overflows in return value. * Make formatting quite a bit faster by inlining dopr_outch() * **************************************************************/ #include "includes.h" #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF # undef HAVE_VSNPRINTF #endif #ifndef VA_COPY # ifdef HAVE_VA_COPY # define VA_COPY(dest, src) va_copy(dest, src) # else # ifdef HAVE___VA_COPY # define VA_COPY(dest, src) __va_copy(dest, src) # else # define VA_COPY(dest, src) (dest) = (src) # endif # endif #endif #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) #include #include #include #include #include #include #ifdef HAVE_LONG_DOUBLE # define LDOUBLE long double #else # define LDOUBLE double #endif #ifdef HAVE_LONG_LONG # define LLONG long long #else # define LLONG long #endif /* * dopr(): poor man's version of doprintf */ /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 #define DP_C_SIZE 5 #define DP_C_INTMAX 6 #define char_to_int(p) ((p)- '0') #ifndef MAX # define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif #define DOPR_OUTCH(buf, pos, buflen, thechar) \ do { \ if (pos + 1 >= INT_MAX) { \ errno = ERANGE; \ return -1; \ } \ if (pos < buflen) \ buf[pos] = thechar; \ (pos)++; \ } while (0) static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in); static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static int fmtint(char *buffer, size_t *currlen, size_t maxlen, intmax_t value, int base, int min, int max, int flags); static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; intmax_t value; LDOUBLE fvalue; char *strvalue; int min; int max; int state; int flags; int cflags; size_t currlen; va_list args; VA_COPY(args, args_in); state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { if (ch == '\0') state = DP_S_DONE; switch(state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; else DOPR_OUTCH(buffer, currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int (ch); ch = *format++; } else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; } else { state = DP_S_DOT; } break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else { state = DP_S_MOD; } break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; } else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; } else { state = DP_S_MOD; } break; case DP_S_MOD: switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'j': cflags = DP_C_INTMAX; ch = *format++; break; case 'l': cflags = DP_C_LONG; ch = *format++; if (ch == 'l') { /* It's a long long */ cflags = DP_C_LLONG; ch = *format++; } break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; case 'z': cflags = DP_C_SIZE; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) value = va_arg (args, int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); else if (cflags == DP_C_LLONG) value = va_arg (args, LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, ssize_t); else if (cflags == DP_C_INTMAX) value = va_arg (args, intmax_t); else value = va_arg (args, int); if (fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags) == -1) return -1; break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (long)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); #ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); #endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags) == -1) return -1; break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); #ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); #endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags) == -1) return -1; break; case 'X': flags |= DP_F_UP; case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else if (cflags == DP_C_SIZE) value = va_arg (args, size_t); #ifdef notyet else if (cflags == DP_C_INTMAX) value = va_arg (args, uintmax_t); #endif else value = (long)va_arg (args, unsigned int); if (fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags) == -1) return -1; break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); if (fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags) == -1) return -1; break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); if (fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags) == -1) return -1; break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); if (fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags) == -1) return -1; break; case 'c': DOPR_OUTCH(buffer, currlen, maxlen, va_arg (args, int)); break; case 's': strvalue = va_arg (args, char *); if (!strvalue) strvalue = "(NULL)"; if (max == -1) { max = strlen(strvalue); } if (min > 0 && max >= 0 && min > max) max = min; if (fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max) == -1) return -1; break; case 'p': strvalue = va_arg (args, void *); if (fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags) == -1) return -1; break; #if we_dont_want_this_in_openssh case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = (long int)currlen; } else if (cflags == DP_C_LLONG) { LLONG *num; num = va_arg (args, LLONG *); *num = (LLONG)currlen; } else if (cflags == DP_C_SIZE) { ssize_t *num; num = va_arg (args, ssize_t *); *num = (ssize_t)currlen; } else if (cflags == DP_C_INTMAX) { intmax_t *num; num = va_arg (args, intmax_t *); *num = (intmax_t)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; #endif case '%': DOPR_OUTCH(buffer, currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } if (maxlen != 0) { if (currlen < maxlen - 1) buffer[currlen] = '\0'; else if (maxlen > 0) buffer[maxlen - 1] = '\0'; } return currlen < INT_MAX ? (int)currlen : -1; } static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; #ifdef DEBUG_SNPRINTF printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); #endif if (value == 0) { value = ""; } for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { DOPR_OUTCH(buffer, *currlen, maxlen, *value); value++; ++cnt; } while ((padlen < 0) && (cnt < max)) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; ++cnt; } return 0; } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static int fmtint(char *buffer, size_t *currlen, size_t maxlen, intmax_t value, int base, int min, int max, int flags) { int signvalue = 0; unsigned LLONG uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if( value < 0 ) { signvalue = '-'; uvalue = -value; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); } while(uvalue && (place < 20)); if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) { --place; DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); } /* Left Justified spaces */ while (spadlen < 0) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++spadlen; } return 0; } static LDOUBLE abs_val(LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE POW10(int val) { LDOUBLE result = 1; while (val) { result *= 10; val--; } return result; } static LLONG ROUND(LDOUBLE value) { LLONG intpart; intpart = (LLONG)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } /* a replacement for modf that doesn't need the math library. Should be portable, but slow */ static double my_modf(double x0, double *iptr) { int i; long l; double x = x0; double f = 1.0; for (i=0;i<100;i++) { l = (long)x; if (l <= (x+1) && l >= (x-1)) break; x *= 0.1; f *= 10.0; } if (i == 100) { /* * yikes! the number is beyond what we can handle. * What do we do? */ (*iptr) = 0; return 0; } if (i != 0) { double i2; double ret; ret = my_modf(x0-l*f, &i2); (*iptr) = l*f + i2; return ret; } (*iptr) = l; return x - (*iptr); } static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; char iconvert[311]; char fconvert[311]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; int idx; double intpart; double fracpart; double temp; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) { signvalue = '-'; } else { if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else { if (flags & DP_F_SPACE) signvalue = ' '; } } #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif #if 0 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ #endif /* * Sorry, we only support 16 digits past the decimal because of our * conversion method */ if (max > 16) max = 16; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ temp = ufvalue; my_modf(temp, &intpart); fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); if (fracpart >= POW10(max)) { intpart++; fracpart -= POW10(max); } /* Convert integer part */ do { temp = intpart*0.1; my_modf(temp, &intpart); idx = (int) ((temp -intpart +0.05)* 10.0); /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; } while (intpart && (iplace < 311)); if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ if (fracpart) { do { temp = fracpart*0.1; my_modf(temp, &fracpart); idx = (int) ((temp -fracpart +0.05)* 10.0); /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; } while(fracpart && (fplace < 311)); if (fplace == 311) fplace--; } fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; } if (signvalue) DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); while (iplace > 0) { --iplace; DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); } #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, '.'); while (zpadlen > 0) { DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } while (fplace > 0) { --fplace; DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); } } while (padlen < 0) { DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; } return 0; } #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ #if !defined(HAVE_VSNPRINTF) int vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif #if !defined(HAVE_SNPRINTF) int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } #endif openssh-7.2p2/openbsd-compat/bsd-statvfs.c010064400017500001750000000040641267006270000167750ustar00djmdjm/* $Id: bsd-statvfs.c,v 1.2 2014/01/17 07:10:59 dtucker Exp $ */ /* * Copyright (c) 2008,2014 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) #include #ifdef HAVE_SYS_MOUNT_H # include #endif #include static void copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from) { to->f_bsize = from->f_bsize; to->f_frsize = from->f_bsize; /* no exact equivalent */ to->f_blocks = from->f_blocks; to->f_bfree = from->f_bfree; to->f_bavail = from->f_bavail; to->f_files = from->f_files; to->f_ffree = from->f_ffree; to->f_favail = from->f_ffree; /* no exact equivalent */ to->f_fsid = 0; /* XXX fix me */ to->f_flag = from->f_flags; to->f_namemax = MNAMELEN; } # ifndef HAVE_STATVFS int statvfs(const char *path, struct statvfs *buf) { # ifdef HAVE_STATFS struct statfs fs; memset(&fs, 0, sizeof(fs)); if (statfs(path, &fs) == -1) return -1; copy_statfs_to_statvfs(buf, &fs); return 0; # else errno = ENOSYS; return -1; # endif } # endif # ifndef HAVE_FSTATVFS int fstatvfs(int fd, struct statvfs *buf) { # ifdef HAVE_FSTATFS struct statfs fs; memset(&fs, 0, sizeof(fs)); if (fstatfs(fd, &fs) == -1) return -1; copy_statfs_to_statvfs(buf, &fs); return 0; # else errno = ENOSYS; return -1; # endif } # endif #endif openssh-7.2p2/openbsd-compat/bsd-statvfs.h010064400017500001750000000044071267006270000170030ustar00djmdjm/* $Id: bsd-statvfs.h,v 1.3 2014/01/17 07:48:22 dtucker Exp $ */ /* * Copyright (c) 2008,2014 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS) #include #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifndef HAVE_FSBLKCNT_T typedef unsigned long fsblkcnt_t; #endif #ifndef HAVE_FSFILCNT_T typedef unsigned long fsfilcnt_t; #endif #ifndef ST_RDONLY #define ST_RDONLY 1 #endif #ifndef ST_NOSUID #define ST_NOSUID 2 #endif /* as defined in IEEE Std 1003.1, 2004 Edition */ struct statvfs { unsigned long f_bsize; /* File system block size. */ unsigned long f_frsize; /* Fundamental file system block size. */ fsblkcnt_t f_blocks; /* Total number of blocks on file system in */ /* units of f_frsize. */ fsblkcnt_t f_bfree; /* Total number of free blocks. */ fsblkcnt_t f_bavail; /* Number of free blocks available to */ /* non-privileged process. */ fsfilcnt_t f_files; /* Total number of file serial numbers. */ fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */ fsfilcnt_t f_favail; /* Number of file serial numbers available to */ /* non-privileged process. */ unsigned long f_fsid; /* File system ID. */ unsigned long f_flag; /* BBit mask of f_flag values. */ unsigned long f_namemax;/* Maximum filename length. */ }; #endif #ifndef HAVE_STATVFS int statvfs(const char *, struct statvfs *); #endif #ifndef HAVE_FSTATVFS int fstatvfs(int, struct statvfs *); #endif openssh-7.2p2/openbsd-compat/bsd-waitpid.c010064400017500001750000000035301267006270000167410ustar00djmdjm/* * Copyright (c) 2000 Ben Lindstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #ifndef HAVE_WAITPID #include #include #include "bsd-waitpid.h" pid_t waitpid(int pid, int *stat_loc, int options) { union wait statusp; pid_t wait_pid; if (pid <= 0) { if (pid != -1) { errno = EINVAL; return (-1); } /* wait4() wants pid=0 for indiscriminate wait. */ pid = 0; } wait_pid = wait4(pid, &statusp, options, NULL); if (stat_loc) *stat_loc = (int) statusp.w_status; return (wait_pid); } #endif /* !HAVE_WAITPID */ openssh-7.2p2/openbsd-compat/bsd-waitpid.h010064400017500001750000000041311267006270000167440ustar00djmdjm/* $Id: bsd-waitpid.h,v 1.5 2003/08/29 16:59:52 mouring Exp $ */ /* * Copyright (c) 2000 Ben Lindstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 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 _BSD_WAITPID_H #define _BSD_WAITPID_H #ifndef HAVE_WAITPID /* Clean out any potental issues */ #undef WIFEXITED #undef WIFSTOPPED #undef WIFSIGNALED /* Define required functions to mimic a POSIX look and feel */ #define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ #define WIFEXITED(w) (!((_W_INT(w)) & 0377)) #define WIFSTOPPED(w) ((_W_INT(w)) & 0100) #define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) #define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) #define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) #define WCOREFLAG 0x80 #define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) /* Prototype */ pid_t waitpid(int, int *, int); #endif /* !HAVE_WAITPID */ #endif /* _BSD_WAITPID_H */ openssh-7.2p2/openbsd-compat/chacha_private.h010064400017500001750000000124151267006270000175020ustar00djmdjm/* chacha-merged.c version 20080118 D. J. Bernstein Public domain. */ /* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ typedef unsigned char u8; typedef unsigned int u32; typedef struct { u32 input[16]; /* could be compressed */ } chacha_ctx; #define U8C(v) (v##U) #define U32C(v) (v##U) #define U8V(v) ((u8)(v) & U8C(0xFF)) #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) #define ROTL32(v, n) \ (U32V((v) << (n)) | ((v) >> (32 - (n)))) #define U8TO32_LITTLE(p) \ (((u32)((p)[0]) ) | \ ((u32)((p)[1]) << 8) | \ ((u32)((p)[2]) << 16) | \ ((u32)((p)[3]) << 24)) #define U32TO8_LITTLE(p, v) \ do { \ (p)[0] = U8V((v) ); \ (p)[1] = U8V((v) >> 8); \ (p)[2] = U8V((v) >> 16); \ (p)[3] = U8V((v) >> 24); \ } while (0) #define ROTATE(v,c) (ROTL32(v,c)) #define XOR(v,w) ((v) ^ (w)) #define PLUS(v,w) (U32V((v) + (w))) #define PLUSONE(v) (PLUS((v),1)) #define QUARTERROUND(a,b,c,d) \ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; static void chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) { const char *constants; x->input[4] = U8TO32_LITTLE(k + 0); x->input[5] = U8TO32_LITTLE(k + 4); x->input[6] = U8TO32_LITTLE(k + 8); x->input[7] = U8TO32_LITTLE(k + 12); if (kbits == 256) { /* recommended */ k += 16; constants = sigma; } else { /* kbits == 128 */ constants = tau; } x->input[8] = U8TO32_LITTLE(k + 0); x->input[9] = U8TO32_LITTLE(k + 4); x->input[10] = U8TO32_LITTLE(k + 8); x->input[11] = U8TO32_LITTLE(k + 12); x->input[0] = U8TO32_LITTLE(constants + 0); x->input[1] = U8TO32_LITTLE(constants + 4); x->input[2] = U8TO32_LITTLE(constants + 8); x->input[3] = U8TO32_LITTLE(constants + 12); } static void chacha_ivsetup(chacha_ctx *x,const u8 *iv) { x->input[12] = 0; x->input[13] = 0; x->input[14] = U8TO32_LITTLE(iv + 0); x->input[15] = U8TO32_LITTLE(iv + 4); } static void chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) { u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; u8 *ctarget = NULL; u8 tmp[64]; u_int i; if (!bytes) return; j0 = x->input[0]; j1 = x->input[1]; j2 = x->input[2]; j3 = x->input[3]; j4 = x->input[4]; j5 = x->input[5]; j6 = x->input[6]; j7 = x->input[7]; j8 = x->input[8]; j9 = x->input[9]; j10 = x->input[10]; j11 = x->input[11]; j12 = x->input[12]; j13 = x->input[13]; j14 = x->input[14]; j15 = x->input[15]; for (;;) { if (bytes < 64) { for (i = 0;i < bytes;++i) tmp[i] = m[i]; m = tmp; ctarget = c; c = tmp; } x0 = j0; x1 = j1; x2 = j2; x3 = j3; x4 = j4; x5 = j5; x6 = j6; x7 = j7; x8 = j8; x9 = j9; x10 = j10; x11 = j11; x12 = j12; x13 = j13; x14 = j14; x15 = j15; for (i = 20;i > 0;i -= 2) { QUARTERROUND( x0, x4, x8,x12) QUARTERROUND( x1, x5, x9,x13) QUARTERROUND( x2, x6,x10,x14) QUARTERROUND( x3, x7,x11,x15) QUARTERROUND( x0, x5,x10,x15) QUARTERROUND( x1, x6,x11,x12) QUARTERROUND( x2, x7, x8,x13) QUARTERROUND( x3, x4, x9,x14) } x0 = PLUS(x0,j0); x1 = PLUS(x1,j1); x2 = PLUS(x2,j2); x3 = PLUS(x3,j3); x4 = PLUS(x4,j4); x5 = PLUS(x5,j5); x6 = PLUS(x6,j6); x7 = PLUS(x7,j7); x8 = PLUS(x8,j8); x9 = PLUS(x9,j9); x10 = PLUS(x10,j10); x11 = PLUS(x11,j11); x12 = PLUS(x12,j12); x13 = PLUS(x13,j13); x14 = PLUS(x14,j14); x15 = PLUS(x15,j15); #ifndef KEYSTREAM_ONLY x0 = XOR(x0,U8TO32_LITTLE(m + 0)); x1 = XOR(x1,U8TO32_LITTLE(m + 4)); x2 = XOR(x2,U8TO32_LITTLE(m + 8)); x3 = XOR(x3,U8TO32_LITTLE(m + 12)); x4 = XOR(x4,U8TO32_LITTLE(m + 16)); x5 = XOR(x5,U8TO32_LITTLE(m + 20)); x6 = XOR(x6,U8TO32_LITTLE(m + 24)); x7 = XOR(x7,U8TO32_LITTLE(m + 28)); x8 = XOR(x8,U8TO32_LITTLE(m + 32)); x9 = XOR(x9,U8TO32_LITTLE(m + 36)); x10 = XOR(x10,U8TO32_LITTLE(m + 40)); x11 = XOR(x11,U8TO32_LITTLE(m + 44)); x12 = XOR(x12,U8TO32_LITTLE(m + 48)); x13 = XOR(x13,U8TO32_LITTLE(m + 52)); x14 = XOR(x14,U8TO32_LITTLE(m + 56)); x15 = XOR(x15,U8TO32_LITTLE(m + 60)); #endif j12 = PLUSONE(j12); if (!j12) { j13 = PLUSONE(j13); /* stopping at 2^70 bytes per nonce is user's responsibility */ } U32TO8_LITTLE(c + 0,x0); U32TO8_LITTLE(c + 4,x1); U32TO8_LITTLE(c + 8,x2); U32TO8_LITTLE(c + 12,x3); U32TO8_LITTLE(c + 16,x4); U32TO8_LITTLE(c + 20,x5); U32TO8_LITTLE(c + 24,x6); U32TO8_LITTLE(c + 28,x7); U32TO8_LITTLE(c + 32,x8); U32TO8_LITTLE(c + 36,x9); U32TO8_LITTLE(c + 40,x10); U32TO8_LITTLE(c + 44,x11); U32TO8_LITTLE(c + 48,x12); U32TO8_LITTLE(c + 52,x13); U32TO8_LITTLE(c + 56,x14); U32TO8_LITTLE(c + 60,x15); if (bytes <= 64) { if (bytes < 64) { for (i = 0;i < bytes;++i) ctarget[i] = c[i]; } x->input[12] = j12; x->input[13] = j13; return; } bytes -= 64; c += 64; #ifndef KEYSTREAM_ONLY m += 64; #endif } } openssh-7.2p2/openbsd-compat/charclass.h010064400017500001750000000012761267006270000165070ustar00djmdjm/* * Public domain, 2008, Todd C. Miller * * $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $ */ /* OPENBSD ORIGINAL: lib/libc/gen/charclass.h */ /* * POSIX character class support for fnmatch() and glob(). */ static struct cclass { const char *name; int (*isctype)(int); } cclasses[] = { { "alnum", isalnum }, { "alpha", isalpha }, { "blank", isblank }, { "cntrl", iscntrl }, { "digit", isdigit }, { "graph", isgraph }, { "lower", islower }, { "print", isprint }, { "punct", ispunct }, { "space", isspace }, { "upper", isupper }, { "xdigit", isxdigit }, { NULL, NULL } }; #define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1) openssh-7.2p2/openbsd-compat/daemon.c010064400017500001750000000045131267006270000157770ustar00djmdjm/* $OpenBSD: daemon.c,v 1.6 2005/08/08 08:05:33 espie Exp $ */ /*- * Copyright (c) 1990, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/daemon.c */ #include "includes.h" #ifndef HAVE_DAEMON #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_UNISTD_H # include #endif int daemon(int nochdir, int noclose) { int fd; switch (fork()) { case -1: return (-1); case 0: break; default: _exit(0); } if (setsid() == -1) return (-1); if (!nochdir) (void)chdir("/"); if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) (void)close (fd); } return (0); } #endif /* !HAVE_DAEMON */ openssh-7.2p2/openbsd-compat/dirname.c010064400017500001750000000035701267006270000161550ustar00djmdjm/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ /* * Copyright (c) 1997, 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/dirname.c */ #include "includes.h" #ifndef HAVE_DIRNAME #include #include #include char * dirname(const char *path) { static char dname[MAXPATHLEN]; size_t len; const char *endp; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { dname[0] = '.'; dname[1] = '\0'; return (dname); } /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; /* Find the start of the dir */ while (endp > path && *endp != '/') endp--; /* Either the dir is "/" or there are no slashes */ if (endp == path) { dname[0] = *endp == '/' ? '/' : '.'; dname[1] = '\0'; return (dname); } else { /* Move forward past the separating slashes */ do { endp--; } while (endp > path && *endp == '/'); } len = endp - path + 1; if (len >= sizeof(dname)) { errno = ENAMETOOLONG; return (NULL); } memcpy(dname, path, len); dname[len] = '\0'; return (dname); } #endif openssh-7.2p2/openbsd-compat/explicit_bzero.c010064400017500001750000000013301267006270000175500ustar00djmdjm/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ /* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */ /* * Public domain. * Written by Ted Unangst */ #include "includes.h" /* * explicit_bzero - don't let the compiler optimize away bzero */ #ifndef HAVE_EXPLICIT_BZERO #ifdef HAVE_MEMSET_S void explicit_bzero(void *p, size_t n) { (void)memset_s(p, n, 0, n); } #else /* HAVE_MEMSET_S */ /* * Indirect bzero through a volatile pointer to hopefully avoid * dead-store optimisation eliminating the call. */ static void (* volatile ssh_bzero)(void *, size_t) = bzero; void explicit_bzero(void *p, size_t n) { ssh_bzero(p, n); } #endif /* HAVE_MEMSET_S */ #endif /* HAVE_EXPLICIT_BZERO */ openssh-7.2p2/openbsd-compat/fake-rfc2553.c010064400017500001750000000142751267006270000165370ustar00djmdjm/* * Copyright (C) 2000-2003 Damien Miller. All rights reserved. * Copyright (C) 1999 WIDE Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Pseudo-implementation of RFC2553 name / address resolution functions * * But these functions are not implemented correctly. The minimum subset * is implemented for ssh use only. For example, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. */ #include "includes.h" #include #include #include #include #ifndef HAVE_GETNAMEINFO int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct sockaddr_in *sin = (struct sockaddr_in *)sa; struct hostent *hp; char tmpserv[16]; if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) return (EAI_FAMILY); if (serv != NULL) { snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); if (strlcpy(serv, tmpserv, servlen) >= servlen) return (EAI_MEMORY); } if (host != NULL) { if (flags & NI_NUMERICHOST) { if (strlcpy(host, inet_ntoa(sin->sin_addr), hostlen) >= hostlen) return (EAI_MEMORY); else return (0); } else { hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); if (hp == NULL) return (EAI_NODATA); if (strlcpy(host, hp->h_name, hostlen) >= hostlen) return (EAI_MEMORY); else return (0); } } return (0); } #endif /* !HAVE_GETNAMEINFO */ #ifndef HAVE_GAI_STRERROR #ifdef HAVE_CONST_GAI_STRERROR_PROTO const char * #else char * #endif gai_strerror(int err) { switch (err) { case EAI_NODATA: return ("no address associated with name"); case EAI_MEMORY: return ("memory allocation failure."); case EAI_NONAME: return ("nodename nor servname provided, or not known"); case EAI_FAMILY: return ("ai_family not supported"); default: return ("unknown/invalid error."); } } #endif /* !HAVE_GAI_STRERROR */ #ifndef HAVE_FREEADDRINFO void freeaddrinfo(struct addrinfo *ai) { struct addrinfo *next; for(; ai != NULL;) { next = ai->ai_next; free(ai); ai = next; } } #endif /* !HAVE_FREEADDRINFO */ #ifndef HAVE_GETADDRINFO static struct addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) { struct addrinfo *ai; ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); if (ai == NULL) return (NULL); memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); ai->ai_addr = (struct sockaddr *)(ai + 1); /* XXX -- ssh doesn't use sa_len */ ai->ai_addrlen = sizeof(struct sockaddr_in); ai->ai_addr->sa_family = ai->ai_family = AF_INET; ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; /* XXX: the following is not generally correct, but does what we want */ if (hints->ai_socktype) ai->ai_socktype = hints->ai_socktype; else ai->ai_socktype = SOCK_STREAM; if (hints->ai_protocol) ai->ai_protocol = hints->ai_protocol; return (ai); } int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { struct hostent *hp; struct servent *sp; struct in_addr in; int i; long int port; u_long addr; port = 0; if (hints && hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET) return (EAI_FAMILY); if (servname != NULL) { char *cp; port = strtol(servname, &cp, 10); if (port > 0 && port <= 65535 && *cp == '\0') port = htons(port); else if ((sp = getservbyname(servname, NULL)) != NULL) port = sp->s_port; else port = 0; } if (hints && hints->ai_flags & AI_PASSIVE) { addr = htonl(0x00000000); if (hostname && inet_aton(hostname, &in) != 0) addr = in.s_addr; *res = malloc_ai(port, addr, hints); if (*res == NULL) return (EAI_MEMORY); return (0); } if (!hostname) { *res = malloc_ai(port, htonl(0x7f000001), hints); if (*res == NULL) return (EAI_MEMORY); return (0); } if (inet_aton(hostname, &in)) { *res = malloc_ai(port, in.s_addr, hints); if (*res == NULL) return (EAI_MEMORY); return (0); } /* Don't try DNS if AI_NUMERICHOST is set */ if (hints && hints->ai_flags & AI_NUMERICHOST) return (EAI_NONAME); hp = gethostbyname(hostname); if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { struct addrinfo *cur, *prev; cur = prev = *res = NULL; for (i = 0; hp->h_addr_list[i]; i++) { struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; cur = malloc_ai(port, in->s_addr, hints); if (cur == NULL) { if (*res != NULL) freeaddrinfo(*res); return (EAI_MEMORY); } if (prev) prev->ai_next = cur; else *res = cur; prev = cur; } return (0); } return (EAI_NODATA); } #endif /* !HAVE_GETADDRINFO */ openssh-7.2p2/openbsd-compat/fake-rfc2553.h010064400017500001750000000124221267006270000165340ustar00djmdjm/* $Id: fake-rfc2553.h,v 1.16 2008/07/14 11:37:37 djm Exp $ */ /* * Copyright (C) 2000-2003 Damien Miller. All rights reserved. * Copyright (C) 1999 WIDE Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Pseudo-implementation of RFC2553 name / address resolution functions * * But these functions are not implemented correctly. The minimum subset * is implemented for ssh use only. For example, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. */ #ifndef _FAKE_RFC2553_H #define _FAKE_RFC2553_H #include "includes.h" #include #if defined(HAVE_NETDB_H) # include #endif /* * First, socket and INET6 related definitions */ #ifndef HAVE_STRUCT_SOCKADDR_STORAGE # define _SS_MAXSIZE 128 /* Implementation specific max size */ # define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) struct sockaddr_storage { struct sockaddr ss_sa; char __ss_pad2[_SS_PADSIZE]; }; # define ss_family ss_sa.sa_family #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ #ifndef IN6_IS_ADDR_LOOPBACK # define IN6_IS_ADDR_LOOPBACK(a) \ (((u_int32_t *)(a))[0] == 0 && ((u_int32_t *)(a))[1] == 0 && \ ((u_int32_t *)(a))[2] == 0 && ((u_int32_t *)(a))[3] == htonl(1)) #endif /* !IN6_IS_ADDR_LOOPBACK */ #ifndef HAVE_STRUCT_IN6_ADDR struct in6_addr { u_int8_t s6_addr[16]; }; #endif /* !HAVE_STRUCT_IN6_ADDR */ #ifndef HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 { unsigned short sin6_family; u_int16_t sin6_port; u_int32_t sin6_flowinfo; struct in6_addr sin6_addr; u_int32_t sin6_scope_id; }; #endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ #ifndef AF_INET6 /* Define it to something that should never appear */ #define AF_INET6 AF_MAX #endif /* * Next, RFC2553 name / address resolution API */ #ifndef NI_NUMERICHOST # define NI_NUMERICHOST (1) #endif #ifndef NI_NAMEREQD # define NI_NAMEREQD (1<<1) #endif #ifndef NI_NUMERICSERV # define NI_NUMERICSERV (1<<2) #endif #ifndef AI_PASSIVE # define AI_PASSIVE (1) #endif #ifndef AI_CANONNAME # define AI_CANONNAME (1<<1) #endif #ifndef AI_NUMERICHOST # define AI_NUMERICHOST (1<<2) #endif #ifndef AI_NUMERICSERV # define AI_NUMERICSERV (1<<3) #endif #ifndef NI_MAXSERV # define NI_MAXSERV 32 #endif /* !NI_MAXSERV */ #ifndef NI_MAXHOST # define NI_MAXHOST 1025 #endif /* !NI_MAXHOST */ #ifndef EAI_NODATA # define EAI_NODATA (INT_MAX - 1) #endif #ifndef EAI_MEMORY # define EAI_MEMORY (INT_MAX - 2) #endif #ifndef EAI_NONAME # define EAI_NONAME (INT_MAX - 3) #endif #ifndef EAI_SYSTEM # define EAI_SYSTEM (INT_MAX - 4) #endif #ifndef EAI_FAMILY # define EAI_FAMILY (INT_MAX - 5) #endif #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; #endif /* !HAVE_STRUCT_ADDRINFO */ #ifndef HAVE_GETADDRINFO #ifdef getaddrinfo # undef getaddrinfo #endif #define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d)) int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); #endif /* !HAVE_GETADDRINFO */ #if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO) #define gai_strerror(a) (_ssh_compat_gai_strerror(a)) char *gai_strerror(int); #endif /* !HAVE_GAI_STRERROR */ #ifndef HAVE_FREEADDRINFO #define freeaddrinfo(a) (ssh_freeaddrinfo(a)) void freeaddrinfo(struct addrinfo *); #endif /* !HAVE_FREEADDRINFO */ #ifndef HAVE_GETNAMEINFO #define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g)) int getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); #endif /* !HAVE_GETNAMEINFO */ #endif /* !_FAKE_RFC2553_H */ openssh-7.2p2/openbsd-compat/fmt_scaled.c010064400017500001750000000161371267006270000166420ustar00djmdjm/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */ /* * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* OPENBSD ORIGINAL: lib/libutil/fmt_scaled.c */ /* * fmt_scaled: Format numbers scaled for human comprehension * scan_scaled: Scan numbers in this format. * * "Human-readable" output uses 4 digits max, and puts a unit suffix at * the end. Makes output compact and easy-to-read esp. on huge disks. * Formatting code was originally in OpenBSD "df", converted to library routine. * Scanning code written for OpenBSD libutil. */ #include "includes.h" #ifndef HAVE_FMT_SCALED #include #include #include #include #include #include typedef enum { NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6 } unit_type; /* These three arrays MUST be in sync! XXX make a struct */ static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA }; static char scale_chars[] = "BKMGTPE"; static long long scale_factors[] = { 1LL, 1024LL, 1024LL*1024, 1024LL*1024*1024, 1024LL*1024*1024*1024, 1024LL*1024*1024*1024*1024, 1024LL*1024*1024*1024*1024*1024, }; #define SCALE_LENGTH (sizeof(units)/sizeof(units[0])) #define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */ /** Convert the given input string "scaled" into numeric in "result". * Return 0 on success, -1 and errno set on error. */ int scan_scaled(char *scaled, long long *result) { char *p = scaled; int sign = 0; unsigned int i, ndigits = 0, fract_digits = 0; long long scale_fact = 1, whole = 0, fpart = 0; /* Skip leading whitespace */ while (isascii(*p) && isspace(*p)) ++p; /* Then at most one leading + or - */ while (*p == '-' || *p == '+') { if (*p == '-') { if (sign) { errno = EINVAL; return -1; } sign = -1; ++p; } else if (*p == '+') { if (sign) { errno = EINVAL; return -1; } sign = +1; ++p; } } /* Main loop: Scan digits, find decimal point, if present. * We don't allow exponentials, so no scientific notation * (but note that E for Exa might look like e to some!). * Advance 'p' to end, to get scale factor. */ for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) { if (*p == '.') { if (fract_digits > 0) { /* oops, more than one '.' */ errno = EINVAL; return -1; } fract_digits = 1; continue; } i = (*p) - '0'; /* whew! finally a digit we can use */ if (fract_digits > 0) { if (fract_digits >= MAX_DIGITS-1) /* ignore extra fractional digits */ continue; fract_digits++; /* for later scaling */ fpart *= 10; fpart += i; } else { /* normal digit */ if (++ndigits >= MAX_DIGITS) { errno = ERANGE; return -1; } whole *= 10; whole += i; } } if (sign) { whole *= sign; fpart *= sign; } /* If no scale factor given, we're done. fraction is discarded. */ if (!*p) { *result = whole; return 0; } /* Validate scale factor, and scale whole and fraction by it. */ for (i = 0; i < SCALE_LENGTH; i++) { /** Are we there yet? */ if (*p == scale_chars[i] || *p == tolower(scale_chars[i])) { /* If it ends with alphanumerics after the scale char, bad. */ if (isalnum(*(p+1))) { errno = EINVAL; return -1; } scale_fact = scale_factors[i]; /* scale whole part */ whole *= scale_fact; /* truncate fpart so it does't overflow. * then scale fractional part. */ while (fpart >= LLONG_MAX / scale_fact) { fpart /= 10; fract_digits--; } fpart *= scale_fact; if (fract_digits > 0) { for (i = 0; i < fract_digits -1; i++) fpart /= 10; } whole += fpart; *result = whole; return 0; } } errno = ERANGE; return -1; } /* Format the given "number" into human-readable form in "result". * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE. * Return 0 on success, -1 and errno set if error. */ int fmt_scaled(long long number, char *result) { long long abval, fract = 0; unsigned int i; unit_type unit = NONE; abval = (number < 0LL) ? -number : number; /* no long long_abs yet */ /* Not every negative long long has a positive representation. * Also check for numbers that are just too darned big to format */ if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) { errno = ERANGE; return -1; } /* scale whole part; get unscaled fraction */ for (i = 0; i < SCALE_LENGTH; i++) { if (abval/1024 < scale_factors[i]) { unit = units[i]; fract = (i == 0) ? 0 : abval % scale_factors[i]; number /= scale_factors[i]; if (i > 0) fract /= scale_factors[i - 1]; break; } } fract = (10 * fract + 512) / 1024; /* if the result would be >= 10, round main number */ if (fract == 10) { if (number >= 0) number++; else number--; fract = 0; } if (number == 0) strlcpy(result, "0B", FMT_SCALED_STRSIZE); else if (unit == NONE || number >= 100 || number <= -100) { if (fract >= 5) { if (number >= 0) number++; else number--; } (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c", number, scale_chars[unit]); } else (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c", number, fract, scale_chars[unit]); return 0; } #ifdef MAIN /* * This is the original version of the program in the man page. * Copy-and-paste whatever you need from it. */ int main(int argc, char **argv) { char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE]; long long ninput = 10483892, result; if (scan_scaled(cinput, &result) == 0) printf("\"%s\" -> %lld\n", cinput, result); else perror(cinput); if (fmt_scaled(ninput, buf) == 0) printf("%lld -> \"%s\"\n", ninput, buf); else fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno)); return 0; } #endif #endif /* HAVE_FMT_SCALED */ openssh-7.2p2/openbsd-compat/getcwd.c010064400017500001750000000137141267006270000160140ustar00djmdjm/* from OpenBSD: getcwd.c,v 1.14 2005/08/08 08:05:34 espie Exp */ /* * Copyright (c) 1989, 1991, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/getcwd.c */ #include "includes.h" #if !defined(HAVE_GETCWD) #include #include #include #include #include #include #include #include #include "includes.h" #define ISDOT(dp) \ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) char * getcwd(char *pt, size_t size) { struct dirent *dp; DIR *dir = NULL; dev_t dev; ino_t ino; int first; char *bpt, *bup; struct stat s; dev_t root_dev; ino_t root_ino; size_t ptsize, upsize; int save_errno; char *ept, *eup, *up; /* * If no buffer specified by the user, allocate one as necessary. * If a buffer is specified, the size has to be non-zero. The path * is built from the end of the buffer backwards. */ if (pt) { ptsize = 0; if (!size) { errno = EINVAL; return (NULL); } ept = pt + size; } else { if ((pt = malloc(ptsize = MAXPATHLEN)) == NULL) return (NULL); ept = pt + ptsize; } bpt = ept - 1; *bpt = '\0'; /* * Allocate bytes for the string of "../"'s. * Should always be enough (it's 340 levels). If it's not, allocate * as necessary. Special * case the first stat, it's ".", not "..". */ if ((up = malloc(upsize = MAXPATHLEN)) == NULL) goto err; eup = up + upsize; bup = up; up[0] = '.'; up[1] = '\0'; /* Save root values, so know when to stop. */ if (stat("/", &s)) goto err; root_dev = s.st_dev; root_ino = s.st_ino; errno = 0; /* XXX readdir has no error return. */ for (first = 1;; first = 0) { /* Stat the current level. */ if (lstat(up, &s)) goto err; /* Save current node values. */ ino = s.st_ino; dev = s.st_dev; /* Check for reaching root. */ if (root_dev == dev && root_ino == ino) { *--bpt = '/'; /* * It's unclear that it's a requirement to copy the * path to the beginning of the buffer, but it's always * been that way and stuff would probably break. */ memmove(pt, bpt, ept - bpt); free(up); return (pt); } /* * Build pointer to the parent directory, allocating memory * as necessary. Max length is 3 for "../", the largest * possible component name, plus a trailing NUL. */ if (bup + 3 + MAXNAMLEN + 1 >= eup) { char *nup; if ((nup = realloc(up, upsize *= 2)) == NULL) goto err; bup = nup + (bup - up); up = nup; eup = up + upsize; } *bup++ = '.'; *bup++ = '.'; *bup = '\0'; /* Open and stat parent directory. */ if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) goto err; /* Add trailing slash for next directory. */ *bup++ = '/'; /* * If it's a mount point, have to stat each element because * the inode number in the directory is for the entry in the * parent directory, not the inode number of the mounted file. */ save_errno = 0; if (s.st_dev == dev) { for (;;) { if (!(dp = readdir(dir))) goto notfound; if (dp->d_fileno == ino) break; } } else for (;;) { if (!(dp = readdir(dir))) goto notfound; if (ISDOT(dp)) continue; memcpy(bup, dp->d_name, dp->d_namlen + 1); /* Save the first error for later. */ if (lstat(up, &s)) { if (!save_errno) save_errno = errno; errno = 0; continue; } if (s.st_dev == dev && s.st_ino == ino) break; } /* * Check for length of the current name, preceding slash, * leading slash. */ if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { size_t len; char *npt; if (!ptsize) { errno = ERANGE; goto err; } len = ept - bpt; if ((npt = realloc(pt, ptsize *= 2)) == NULL) goto err; bpt = npt + (bpt - pt); pt = npt; ept = pt + ptsize; memmove(ept - len, bpt, len); bpt = ept - len; } if (!first) *--bpt = '/'; bpt -= dp->d_namlen; memcpy(bpt, dp->d_name, dp->d_namlen); (void)closedir(dir); /* Truncate any file name. */ *bup = '\0'; } notfound: /* * If readdir set errno, use it, not any saved error; otherwise, * didn't find the current directory in its parent directory, set * errno to ENOENT. */ if (!errno) errno = save_errno ? save_errno : ENOENT; /* FALLTHROUGH */ err: save_errno = errno; if (ptsize) free(pt); free(up); if (dir) (void)closedir(dir); errno = save_errno; return (NULL); } #endif /* !defined(HAVE_GETCWD) */ openssh-7.2p2/openbsd-compat/getgrouplist.c010064400017500001750000000053231267006270000172640ustar00djmdjm/* from OpenBSD: getgrouplist.c,v 1.12 2005/08/08 08:05:34 espie Exp */ /* * Copyright (c) 1991, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/getgrouplist.c */ #include "includes.h" #ifndef HAVE_GETGROUPLIST /* * get credential */ #include #include #include #include int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) { struct group *grp; int i, ngroups; int ret, maxgroups; int bail; ret = 0; ngroups = 0; maxgroups = *grpcnt; /* * install primary group */ if (ngroups >= maxgroups) { *grpcnt = ngroups; return (-1); } groups[ngroups++] = agroup; /* * Scan the group file to find additional groups. */ setgrent(); while ((grp = getgrent())) { if (grp->gr_gid == agroup) continue; for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) if (groups[i] == grp->gr_gid) bail = 1; if (bail) continue; for (i = 0; grp->gr_mem[i]; i++) { if (!strcmp(grp->gr_mem[i], uname)) { if (ngroups >= maxgroups) { ret = -1; goto out; } groups[ngroups++] = grp->gr_gid; break; } } } out: endgrent(); *grpcnt = ngroups; return (ret); } #endif /* HAVE_GETGROUPLIST */ openssh-7.2p2/openbsd-compat/getopt.h010064400017500001750000000053221267006270000160420ustar00djmdjm/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */ /* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Dieter Baron and Thomas Klausner. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ #ifndef _GETOPT_H_ #define _GETOPT_H_ /* * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 struct option { /* name of long option */ const char *name; /* * one of no_argument, required_argument, and optional_argument: * whether option takes an argument */ int has_arg; /* if not NULL, set *flag to val when option found */ int *flag; /* if flag not NULL, value to set *flag to; else return value */ int val; }; int getopt_long(int, char * const *, const char *, const struct option *, int *); int getopt_long_only(int, char * const *, const char *, const struct option *, int *); #ifndef _GETOPT_DEFINED_ #define _GETOPT_DEFINED_ int getopt(int, char * const *, const char *); int getsubopt(char **, char * const *, char **); extern char *optarg; /* getopt(3) external variables */ extern int opterr; extern int optind; extern int optopt; extern int optreset; extern char *suboptarg; /* getsubopt(3) external variable */ #endif #endif /* !_GETOPT_H_ */ openssh-7.2p2/openbsd-compat/getopt_long.c010064400017500001750000000347331267006270000170640ustar00djmdjm/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ /* * Copyright (c) 2002 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Dieter Baron and Thomas Klausner. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */ #include "includes.h" #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) /* * Some defines to make it easier to keep the code in sync with upstream. * getopt opterr optind optopt optreset optarg are all in defines.h which is * pulled in by includes.h. */ #define warnx logit #if 0 #include #include #endif #include #include #include #include #include "log.h" int opterr = 1; /* if error message should be printed */ int optind = 1; /* index into parent argv vector */ int optopt = '?'; /* character checked for validity */ int optreset; /* reset getopt */ char *optarg; /* argument associated with option */ #define PRINT_ERROR ((opterr) && (*options != ':')) #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ /* return values */ #define BADCH (int)'?' #define BADARG ((*options == ':') ? (int)':' : (int)'?') #define INORDER (int)1 #define EMSG "" static int getopt_internal(int, char * const *, const char *, const struct option *, int *, int); static int parse_long_options(char * const *, const char *, const struct option *, int *, int); static int gcd(int, int); static void permute_args(int, int, int, char * const *); static char *place = EMSG; /* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start = -1; /* first non option argument (for permute) */ static int nonopt_end = -1; /* first option after non options (for permute) */ /* Error messages */ static const char recargchar[] = "option requires an argument -- %c"; static const char recargstring[] = "option requires an argument -- %s"; static const char ambig[] = "ambiguous option -- %.*s"; static const char noarg[] = "option doesn't take an argument -- %.*s"; static const char illoptchar[] = "unknown option -- %c"; static const char illoptstring[] = "unknown option -- %s"; /* * Compute the greatest common divisor of a and b. */ static int gcd(int a, int b) { int c; c = a % b; while (c != 0) { a = b; b = c; c = a % b; } return (b); } /* * Exchange the block from nonopt_start to nonopt_end with the block * from nonopt_end to opt_end (keeping the same order of arguments * in each block). */ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv) { int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; char *swap; /* * compute lengths of blocks and number and size of cycles */ nnonopts = panonopt_end - panonopt_start; nopts = opt_end - panonopt_end; ncycle = gcd(nnonopts, nopts); cyclelen = (opt_end - panonopt_start) / ncycle; for (i = 0; i < ncycle; i++) { cstart = panonopt_end+i; pos = cstart; for (j = 0; j < cyclelen; j++) { if (pos >= panonopt_end) pos -= nnonopts; else pos += nopts; swap = nargv[pos]; /* LINTED const cast */ ((char **) nargv)[pos] = nargv[cstart]; /* LINTED const cast */ ((char **)nargv)[cstart] = swap; } } } /* * parse_long_options -- * Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */ static int parse_long_options(char * const *nargv, const char *options, const struct option *long_options, int *idx, int short_too) { char *current_argv, *has_equal; size_t current_argv_len; int i, match; current_argv = place; match = -1; optind++; if ((has_equal = strchr(current_argv, '=')) != NULL) { /* argument found (--option=arg) */ current_argv_len = has_equal - current_argv; has_equal++; } else current_argv_len = strlen(current_argv); for (i = 0; long_options[i].name; i++) { /* find matching long option */ if (strncmp(current_argv, long_options[i].name, current_argv_len)) continue; if (strlen(long_options[i].name) == current_argv_len) { /* exact match */ match = i; break; } /* * If this is a known short option, don't allow * a partial match of a single character. */ if (short_too && current_argv_len == 1) continue; if (match == -1) /* partial match */ match = i; else { /* ambiguous abbreviation */ if (PRINT_ERROR) warnx(ambig, (int)current_argv_len, current_argv); optopt = 0; return (BADCH); } } if (match != -1) { /* option found */ if (long_options[match].has_arg == no_argument && has_equal) { if (PRINT_ERROR) warnx(noarg, (int)current_argv_len, current_argv); /* * XXX: GNU sets optopt to val regardless of flag */ if (long_options[match].flag == NULL) optopt = long_options[match].val; else optopt = 0; return (BADARG); } if (long_options[match].has_arg == required_argument || long_options[match].has_arg == optional_argument) { if (has_equal) optarg = has_equal; else if (long_options[match].has_arg == required_argument) { /* * optional argument doesn't use next nargv */ optarg = nargv[optind++]; } } if ((long_options[match].has_arg == required_argument) && (optarg == NULL)) { /* * Missing argument; leading ':' indicates no error * should be generated. */ if (PRINT_ERROR) warnx(recargstring, current_argv); /* * XXX: GNU sets optopt to val regardless of flag */ if (long_options[match].flag == NULL) optopt = long_options[match].val; else optopt = 0; --optind; return (BADARG); } } else { /* unknown option */ if (short_too) { --optind; return (-1); } if (PRINT_ERROR) warnx(illoptstring, current_argv); optopt = 0; return (BADCH); } if (idx) *idx = match; if (long_options[match].flag) { *long_options[match].flag = long_options[match].val; return (0); } else return (long_options[match].val); } /* * getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */ static int getopt_internal(int nargc, char * const *nargv, const char *options, const struct option *long_options, int *idx, int flags) { char *oli; /* option letter list index */ int optchar, short_too; static int posixly_correct = -1; if (options == NULL) return (-1); /* * XXX Some GNU programs (like cvs) set optind to 0 instead of * XXX using optreset. Work around this braindamage. */ if (optind == 0) optind = optreset = 1; /* * Disable GNU extensions if POSIXLY_CORRECT is set or options * string begins with a '+'. */ if (posixly_correct == -1 || optreset) posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); if (*options == '-') flags |= FLAG_ALLARGS; else if (posixly_correct || *options == '+') flags &= ~FLAG_PERMUTE; if (*options == '+' || *options == '-') options++; optarg = NULL; if (optreset) nonopt_start = nonopt_end = -1; start: if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc) { /* end of argument vector */ place = EMSG; if (nonopt_end != -1) { /* do permutation, if we have to */ permute_args(nonopt_start, nonopt_end, optind, nargv); optind -= nonopt_end - nonopt_start; } else if (nonopt_start != -1) { /* * If we skipped non-options, set optind * to the first of them. */ optind = nonopt_start; } nonopt_start = nonopt_end = -1; return (-1); } if (*(place = nargv[optind]) != '-' || (place[1] == '\0' && strchr(options, '-') == NULL)) { place = EMSG; /* found non-option */ if (flags & FLAG_ALLARGS) { /* * GNU extension: * return non-option as argument to option 1 */ optarg = nargv[optind++]; return (INORDER); } if (!(flags & FLAG_PERMUTE)) { /* * If no permutation wanted, stop parsing * at first non-option. */ return (-1); } /* do permutation */ if (nonopt_start == -1) nonopt_start = optind; else if (nonopt_end != -1) { permute_args(nonopt_start, nonopt_end, optind, nargv); nonopt_start = optind - (nonopt_end - nonopt_start); nonopt_end = -1; } optind++; /* process next argument */ goto start; } if (nonopt_start != -1 && nonopt_end == -1) nonopt_end = optind; /* * If we have "-" do nothing, if "--" we are done. */ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { optind++; place = EMSG; /* * We found an option (--), so if we skipped * non-options, we have to permute. */ if (nonopt_end != -1) { permute_args(nonopt_start, nonopt_end, optind, nargv); optind -= nonopt_end - nonopt_start; } nonopt_start = nonopt_end = -1; return (-1); } } /* * Check long options if: * 1) we were passed some * 2) the arg is not just "-" * 3) either the arg starts with -- we are getopt_long_only() */ if (long_options != NULL && place != nargv[optind] && (*place == '-' || (flags & FLAG_LONGONLY))) { short_too = 0; if (*place == '-') place++; /* --foo long option */ else if (*place != ':' && strchr(options, *place) != NULL) short_too = 1; /* could be short option too */ optchar = parse_long_options(nargv, options, long_options, idx, short_too); if (optchar != -1) { place = EMSG; return (optchar); } } if ((optchar = (int)*place++) == (int)':' || (optchar == (int)'-' && *place != '\0') || (oli = strchr(options, optchar)) == NULL) { /* * If the user specified "-" and '-' isn't listed in * options, return -1 (non-option) as per POSIX. * Otherwise, it is an unknown option character (or ':'). */ if (optchar == (int)'-' && *place == '\0') return (-1); if (!*place) ++optind; if (PRINT_ERROR) warnx(illoptchar, optchar); optopt = optchar; return (BADCH); } if (long_options != NULL && optchar == 'W' && oli[1] == ';') { /* -W long-option */ if (*place) /* no space */ /* NOTHING */; else if (++optind >= nargc) { /* no arg */ place = EMSG; if (PRINT_ERROR) warnx(recargchar, optchar); optopt = optchar; return (BADARG); } else /* white space */ place = nargv[optind]; optchar = parse_long_options(nargv, options, long_options, idx, 0); place = EMSG; return (optchar); } if (*++oli != ':') { /* doesn't take argument */ if (!*place) ++optind; } else { /* takes (optional) argument */ optarg = NULL; if (*place) /* no white space */ optarg = place; else if (oli[1] != ':') { /* arg not optional */ if (++optind >= nargc) { /* no arg */ place = EMSG; if (PRINT_ERROR) warnx(recargchar, optchar); optopt = optchar; return (BADARG); } else optarg = nargv[optind]; } place = EMSG; ++optind; } /* dump back option letter */ return (optchar); } /* * getopt -- * Parse argc/argv argument vector. * * [eventually this will replace the BSD getopt] */ int getopt(int nargc, char * const *nargv, const char *options) { /* * We don't pass FLAG_PERMUTE to getopt_internal() since * the BSD getopt(3) (unlike GNU) has never done this. * * Furthermore, since many privileged programs call getopt() * before dropping privileges it makes sense to keep things * as simple (and bug-free) as possible. */ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); } #if 0 /* * getopt_long -- * Parse argc/argv argument vector. */ int getopt_long(int nargc, char * const *nargv, const char *options, const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE)); } /* * getopt_long_only -- * Parse argc/argv argument vector. */ int getopt_long_only(int nargc, char * const *nargv, const char *options, const struct option *long_options, int *idx) { return (getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE|FLAG_LONGONLY)); } #endif #endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ openssh-7.2p2/openbsd-compat/glob.c010064400017500001750000000630331267006270000154610ustar00djmdjm/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/glob.c */ /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * * The [!...] convention to negate a range is supported (SysV, Posix, ksh). * * Optional extra services, controlled by flags not defined by POSIX: * * GLOB_QUOTE: * Escaping convention: \ inhibits any special meaning the following * character might have (except \ at end of string is retained). * GLOB_MAGCHAR: * Set in gl_flags if pattern contained a globbing character. * GLOB_NOMAGIC: * Same as GLOB_NOCHECK, but it will only append pattern if it did * not contain any magic characters. [Used in csh style globbing] * GLOB_ALTDIRFUNC: * Use alternately specified directory access functions. * GLOB_TILDE: * expand ~user/foo to the /home/dir/of/user/foo * GLOB_BRACE: * expand {1,2}{a,b} to 1a 1b 2a 2b * gl_matchc: * Number of matches in the current invocation of glob. */ #include "includes.h" #include "glob.h" #include #include #include #include #include #include #include #include #include #include #if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \ !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ defined(BROKEN_GLOB) #include "charclass.h" #define DOLLAR '$' #define DOT '.' #define EOS '\0' #define LBRACKET '[' #define NOT '!' #define QUESTION '?' #define QUOTE '\\' #define RANGE '-' #define RBRACKET ']' #define SEP '/' #define STAR '*' #define TILDE '~' #define UNDERSCORE '_' #define LBRACE '{' #define RBRACE '}' #define SLASH '/' #define COMMA ',' #ifndef DEBUG #define M_QUOTE 0x8000 #define M_PROTECT 0x4000 #define M_MASK 0xffff #define M_ASCII 0x00ff typedef u_short Char; #else #define M_QUOTE 0x80 #define M_PROTECT 0x40 #define M_MASK 0xff #define M_ASCII 0x7f typedef char Char; #endif #define CHAR(c) ((Char)((c)&M_ASCII)) #define META(c) ((Char)((c)|M_QUOTE)) #define M_ALL META('*') #define M_END META(']') #define M_NOT META('!') #define M_ONE META('?') #define M_RNG META('-') #define M_SET META('[') #define M_CLASS META(':') #define ismeta(c) (((c)&M_QUOTE) != 0) #define GLOB_LIMIT_MALLOC 65536 #define GLOB_LIMIT_STAT 128 #define GLOB_LIMIT_READDIR 16384 /* Limit of recursion during matching attempts. */ #define GLOB_LIMIT_RECUR 64 struct glob_lim { size_t glim_malloc; size_t glim_stat; size_t glim_readdir; }; struct glob_path_stat { char *gps_path; struct stat *gps_stat; }; static int compare(const void *, const void *); static int compare_gps(const void *, const void *); static int g_Ctoc(const Char *, char *, u_int); static int g_lstat(Char *, struct stat *, glob_t *); static DIR *g_opendir(Char *, glob_t *); static Char *g_strchr(const Char *, int); static int g_strncmp(const Char *, const char *, size_t); static int g_stat(Char *, struct stat *, glob_t *); static int glob0(const Char *, glob_t *, struct glob_lim *); static int glob1(Char *, Char *, glob_t *, struct glob_lim *); static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_lim *); static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_lim *); static int globextend(const Char *, glob_t *, struct glob_lim *, struct stat *); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); static int globexp1(const Char *, glob_t *, struct glob_lim *); static int globexp2(const Char *, const Char *, glob_t *, struct glob_lim *); static int match(Char *, Char *, Char *, int); #ifdef DEBUG static void qprintf(const char *, Char *); #endif int glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) { const u_char *patnext; int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN]; struct glob_lim limit = { 0, 0, 0 }; if (strnlen(pattern, PATH_MAX) == PATH_MAX) return(GLOB_NOMATCH); patnext = (u_char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; pglob->gl_statv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 || pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX || pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1) return GLOB_NOSPACE; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; if (flags & GLOB_NOESCAPE) while (bufnext < bufend && (c = *patnext++) != EOS) *bufnext++ = c; else { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != EOS) if (c == QUOTE) { if ((c = *patnext++) == EOS) { c = QUOTE; --patnext; } *bufnext++ = c | M_PROTECT; } else *bufnext++ = c; } *bufnext = EOS; if (flags & GLOB_BRACE) return globexp1(patbuf, pglob, &limit); else return glob0(patbuf, pglob, &limit); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char* ptr = pattern; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob, limitp); if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) return globexp2(ptr, pattern, pglob, limitp); return glob0(pattern, pglob, limitp); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { int i, rv; Char *lm, *ls; const Char *pe, *pm, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) ; *lm = EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe; pe++) if (*pe == LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) ; if (*pe == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pe = pm; } } else if (*pe == LBRACE) i++; else if (*pe == RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) return glob0(patbuf, pglob, limitp); for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { case LBRACKET: /* Ignore everything between [] */ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) ; if (*pm == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pm = pl; } break; case LBRACE: i++; break; case RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case COMMA: if (i && *pm == COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) ; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != EOS; ) ; /* Expand the current pattern */ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif rv = globexp1(patbuf, pglob, limitp); if (rv && rv != GLOB_NOMATCH) return rv; /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } } return 0; } /* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h; const Char *p; Char *b, *eb; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, h = (char *) patbuf; h < (char *)eb && *p && *p != SLASH; *h++ = *p++) ; *h = EOS; #if 0 if (h == (char *)eb) return what; #endif if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ #if 0 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { #endif if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; b < eb && *h; *b++ = *h++) ; /* Append the rest of the pattern */ while (b < eb && (*b++ = *p++) != EOS) ; *b = EOS; return patbuf; } static int g_strncmp(const Char *s1, const char *s2, size_t n) { int rv = 0; while (n--) { rv = *(Char *)s1 - *(const unsigned char *)s2++; if (rv) break; if (*s1++ == '\0') break; } return rv; } static int g_charclass(const Char **patternp, Char **bufnextp) { const Char *pattern = *patternp + 1; Char *bufnext = *bufnextp; const Char *colon; struct cclass *cc; size_t len; if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']') return 1; /* not a character class */ len = (size_t)(colon - pattern); for (cc = cclasses; cc->name != NULL; cc++) { if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0') break; } if (cc->name == NULL) return -1; /* invalid character class */ *bufnext++ = M_CLASS; *bufnext++ = (Char)(cc - &cclasses[0]); *bufnextp = bufnext; *patternp += len + 3; return 0; } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { if (c == LBRACKET && *qpatnext == ':') { do { err = g_charclass(&qpatnext, &bufnext); if (err) break; c = *qpatnext++; } while (c == LBRACKET && *qpatnext == ':'); if (err == -1 && !(pglob->gl_flags & GLOB_NOCHECK)) return GLOB_NOMATCH; if (c == RBRACKET) break; } *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return(globextend(pattern, pglob, limitp, NULL)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) { if ((pglob->gl_flags & GLOB_KEEPSTAT)) { /* Keep the paths and stat info synced during sort */ struct glob_path_stat *path_stat; int i; int n = pglob->gl_pathc - oldpathc; int o = pglob->gl_offs + oldpathc; if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) return GLOB_NOSPACE; for (i = 0; i < n; i++) { path_stat[i].gps_path = pglob->gl_pathv[o + i]; path_stat[i].gps_stat = pglob->gl_statv[o + i]; } qsort(path_stat, n, sizeof(*path_stat), compare_gps); for (i = 0; i < n; i++) { pglob->gl_pathv[o + i] = path_stat[i].gps_path; pglob->gl_statv[o + i] = path_stat[i].gps_stat; } free(path_stat); } else { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } } return(0); } static int compare(const void *p, const void *q) { return(strcmp(*(char **)p, *(char **)q)); } static int compare_gps(const void *_p, const void *_q) { const struct glob_path_stat *p = (const struct glob_path_stat *)_p; const struct glob_path_stat *q = (const struct glob_path_stat *)_q; return(strcmp(p->gps_path, q->gps_path)); } static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, pattern, pattern_last, pglob, limitp)); } /* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { struct stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if ((pglob->gl_flags & GLOB_LIMIT) && limitp->glim_stat++ >= GLOB_LIMIT_STAT) { errno = 0; *pathend++ = SEP; *pathend = EOS; return(GLOB_NOSPACE); } if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend+1 > pathend_last) return (1); *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return(globextend(pathbuf, pglob, limitp, &sb)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; if (q+1 > pathend_last) return (1); *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == SEP) { if (pathend+1 > pathend_last) return (1); *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp)); } /* NOTREACHED */ } static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, struct glob_lim *limitp) { struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(void *); if (pathend > pathend_last) return (1); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) return(GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return(GLOB_ABORTED); } return(0); } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else readdirfunc = (struct dirent *(*)(void *))readdir; while ((dp = (*readdirfunc)(dirp))) { u_char *sc; Char *dc; if ((pglob->gl_flags & GLOB_LIMIT) && limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) { errno = 0; *pathend++ = SEP; *pathend = EOS; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; dc = pathend; sc = (u_char *) dp->d_name; while (dc < pathend_last && (*dc++ = *sc++) != EOS) ; if (dc >= pathend_last) { *dc = EOS; err = 1; break; } if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) { *pathend = EOS; continue; } err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, restpattern, restpattern_last, pglob, limitp); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); return(err); } /* * Extend the gl_pathv member of a glob_t structure to accommodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, struct stat *sb) { char **pathv; ssize_t i; size_t newn, len; char *copy = NULL; const Char *p; struct stat **statv; newn = 2 + pglob->gl_pathc + pglob->gl_offs; if (pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX || newn >= INT_MAX || SIZE_MAX / sizeof(*pathv) <= newn || SIZE_MAX / sizeof(*statv) <= newn) { nospace: for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) { if (pglob->gl_pathv && pglob->gl_pathv[i]) free(pglob->gl_pathv[i]); if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && pglob->gl_pathv && pglob->gl_pathv[i]) free(pglob->gl_statv[i]); } if (pglob->gl_pathv) { free(pglob->gl_pathv); pglob->gl_pathv = NULL; } if (pglob->gl_statv) { free(pglob->gl_statv); pglob->gl_statv = NULL; } return(GLOB_NOSPACE); } pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv)); if (pathv == NULL) goto nospace; if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; for (i = pglob->gl_offs; --i >= 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) { statv = realloc(pglob->gl_statv, newn * sizeof(*statv)); if (statv == NULL) goto nospace; if (pglob->gl_statv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ statv += pglob->gl_offs; for (i = pglob->gl_offs; --i >= 0; ) *--statv = NULL; } pglob->gl_statv = statv; if (sb == NULL) statv[pglob->gl_offs + pglob->gl_pathc] = NULL; else { limitp->glim_malloc += sizeof(**statv); if ((pglob->gl_flags & GLOB_LIMIT) && limitp->glim_malloc >= GLOB_LIMIT_MALLOC) { errno = 0; return(GLOB_NOSPACE); } if ((statv[pglob->gl_offs + pglob->gl_pathc] = malloc(sizeof(**statv))) == NULL) goto copy_error; memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb, sizeof(*sb)); } statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL; } for (p = path; *p++;) ; len = (size_t)(p - path); limitp->glim_malloc += len; if ((copy = malloc(len)) != NULL) { if (g_Ctoc(path, copy, len)) { free(copy); return(GLOB_NOSPACE); } pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; if ((pglob->gl_flags & GLOB_LIMIT) && (newn * sizeof(*pathv)) + limitp->glim_malloc > GLOB_LIMIT_MALLOC) { errno = 0; return(GLOB_NOSPACE); } copy_error: return(copy == NULL ? GLOB_NOSPACE : 0); } /* * pattern matching function for filenames. Each occurrence of the * * pattern causes a recursion level. */ static int match(Char *name, Char *pat, Char *patend, int recur) { int ok, negate_range; Char c, k; if (recur-- == 0) return(GLOB_NOSPACE); while (pat < patend) { c = *pat++; switch (c & M_MASK) { case M_ALL: while (pat < patend && (*pat & M_MASK) == M_ALL) pat++; /* eat consecutive '*' */ if (pat == patend) return(1); do { if (match(name, pat, patend, recur)) return(1); } while (*name++ != EOS); return(0); case M_ONE: if (*name++ == EOS) return(0); break; case M_SET: ok = 0; if ((k = *name++) == EOS) return(0); if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++pat; while (((c = *pat++) & M_MASK) != M_END) { if ((c & M_MASK) == M_CLASS) { Char idx = *pat & M_MASK; if (idx < NCCLASSES && cclasses[idx].isctype(k)) ok = 1; ++pat; } if ((*pat & M_MASK) == M_RNG) { if (c <= k && k <= pat[1]) ok = 1; pat += 2; } else if (c == k) ok = 1; } if (ok == negate_range) return(0); break; default: if (*name++ != c) return(0); break; } } return(*name == EOS); } /* Free allocated data belonging to a glob_t structure. */ void globfree(glob_t *pglob) { int i; char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) free(*pp); free(pglob->gl_pathv); pglob->gl_pathv = NULL; } if (pglob->gl_statv != NULL) { for (i = 0; i < pglob->gl_pathc; i++) { if (pglob->gl_statv[i] != NULL) free(pglob->gl_statv[i]); } free(pglob->gl_statv); pglob->gl_statv = NULL; } } static DIR * g_opendir(Char *str, glob_t *pglob) { char buf[MAXPATHLEN]; if (!*str) strlcpy(buf, ".", sizeof buf); else { if (g_Ctoc(str, buf, sizeof(buf))) return(NULL); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_opendir)(buf)); return(opendir(buf)); } static int g_lstat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN]; if (g_Ctoc(fn, buf, sizeof(buf))) return(-1); if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return(lstat(buf, sb)); } static int g_stat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN]; if (g_Ctoc(fn, buf, sizeof(buf))) return(-1); if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_stat)(buf, sb)); return(stat(buf, sb)); } static Char * g_strchr(const Char *str, int ch) { do { if (*str == ch) return ((Char *)str); } while (*str++); return (NULL); } static int g_Ctoc(const Char *str, char *buf, u_int len) { while (len--) { if ((*buf++ = *str++) == EOS) return (0); } return (1); } #ifdef DEBUG static void qprintf(const char *str, Char *s) { Char *p; (void)printf("%s:\n", str); for (p = s; *p; p++) (void)printf("%c", CHAR(*p)); (void)printf("\n"); for (p = s; *p; p++) (void)printf("%c", *p & M_PROTECT ? '"' : ' '); (void)printf("\n"); for (p = s; *p; p++) (void)printf("%c", ismeta(*p) ? '_' : ' '); (void)printf("\n"); } #endif #endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */ openssh-7.2p2/openbsd-compat/getrrsetbyname-ldns.c010064400017500001750000000174761267006270000205410ustar00djmdjm/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ /* * Copyright (c) 2007 Simon Vallet / Genoscope * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright (c) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #if !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) #include #include #include #include "getrrsetbyname.h" #include "log.h" #include "xmalloc.h" #define malloc(x) (xmalloc(x)) #define calloc(x, y) (xcalloc((x),(y))) int getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { int result; unsigned int i, j, index_ans, index_sig; struct rrsetinfo *rrset = NULL; struct rdatainfo *rdata; size_t len; ldns_resolver *ldns_res = NULL; ldns_rdf *domain = NULL; ldns_pkt *pkt = NULL; ldns_rr_list *rrsigs = NULL, *rrdata = NULL; ldns_status err; ldns_rr *rr; /* check for invalid class and type */ if (rdclass > 0xffff || rdtype > 0xffff) { result = ERRSET_INVAL; goto fail; } /* don't allow queries of class or type ANY */ if (rdclass == 0xff || rdtype == 0xff) { result = ERRSET_INVAL; goto fail; } /* don't allow flags yet, unimplemented */ if (flags) { result = ERRSET_INVAL; goto fail; } /* Initialize resolver from resolv.conf */ domain = ldns_dname_new_frm_str(hostname); if ((err = ldns_resolver_new_frm_file(&ldns_res, NULL)) != \ LDNS_STATUS_OK) { result = ERRSET_FAIL; goto fail; } #ifdef LDNS_DEBUG ldns_resolver_set_debug(ldns_res, true); #endif /* LDNS_DEBUG */ ldns_resolver_set_dnssec(ldns_res, true); /* Use DNSSEC */ /* make query */ pkt = ldns_resolver_query(ldns_res, domain, rdtype, rdclass, LDNS_RD); /*** TODO: finer errcodes -- see original **/ if (!pkt || ldns_pkt_ancount(pkt) < 1) { result = ERRSET_FAIL; goto fail; } /* initialize rrset */ rrset = calloc(1, sizeof(struct rrsetinfo)); if (rrset == NULL) { result = ERRSET_NOMEMORY; goto fail; } rrdata = ldns_pkt_rr_list_by_type(pkt, rdtype, LDNS_SECTION_ANSWER); rrset->rri_nrdatas = ldns_rr_list_rr_count(rrdata); if (!rrset->rri_nrdatas) { result = ERRSET_NODATA; goto fail; } /* copy name from answer section */ len = ldns_rdf_size(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))); if ((rrset->rri_name = malloc(len)) == NULL) { result = ERRSET_NOMEMORY; goto fail; } memcpy(rrset->rri_name, ldns_rdf_data(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))), len); rrset->rri_rdclass = ldns_rr_get_class(ldns_rr_list_rr(rrdata, 0)); rrset->rri_rdtype = ldns_rr_get_type(ldns_rr_list_rr(rrdata, 0)); rrset->rri_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrdata, 0)); debug2("ldns: got %u answers from DNS", rrset->rri_nrdatas); /* Check for authenticated data */ if (ldns_pkt_ad(pkt)) { rrset->rri_flags |= RRSET_VALIDATED; } else { /* AD is not set, try autonomous validation */ ldns_rr_list * trusted_keys = ldns_rr_list_new(); debug2("ldns: trying to validate RRset"); /* Get eventual sigs */ rrsigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANSWER); rrset->rri_nsigs = ldns_rr_list_rr_count(rrsigs); debug2("ldns: got %u signature(s) (RRTYPE %u) from DNS", rrset->rri_nsigs, LDNS_RR_TYPE_RRSIG); if ((err = ldns_verify_trusted(ldns_res, rrdata, rrsigs, trusted_keys)) == LDNS_STATUS_OK) { rrset->rri_flags |= RRSET_VALIDATED; debug2("ldns: RRset is signed with a valid key"); } else { debug2("ldns: RRset validation failed: %s", ldns_get_errorstr_by_id(err)); } ldns_rr_list_deep_free(trusted_keys); } /* allocate memory for answers */ rrset->rri_rdatas = calloc(rrset->rri_nrdatas, sizeof(struct rdatainfo)); if (rrset->rri_rdatas == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* allocate memory for signatures */ if (rrset->rri_nsigs > 0) { rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } } /* copy answers & signatures */ for (i=0, index_ans=0, index_sig=0; i< pkt->_header->_ancount; i++) { rdata = NULL; rr = ldns_rr_list_rr(ldns_pkt_answer(pkt), i); if (ldns_rr_get_class(rr) == rrset->rri_rdclass && ldns_rr_get_type(rr) == rrset->rri_rdtype) { rdata = &rrset->rri_rdatas[index_ans++]; } if (rr->_rr_class == rrset->rri_rdclass && rr->_rr_type == LDNS_RR_TYPE_RRSIG && rrset->rri_sigs) { rdata = &rrset->rri_sigs[index_sig++]; } if (rdata) { size_t rdata_offset = 0; rdata->rdi_length = 0; for (j=0; j< rr->_rd_count; j++) { rdata->rdi_length += ldns_rdf_size(ldns_rr_rdf(rr, j)); } rdata->rdi_data = malloc(rdata->rdi_length); if (rdata->rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* Re-create the raw DNS RDATA */ for (j=0; j< rr->_rd_count; j++) { len = ldns_rdf_size(ldns_rr_rdf(rr, j)); memcpy(rdata->rdi_data + rdata_offset, ldns_rdf_data(ldns_rr_rdf(rr, j)), len); rdata_offset += len; } } } *res = rrset; result = ERRSET_SUCCESS; fail: /* freerrset(rrset); */ ldns_rdf_deep_free(domain); ldns_pkt_free(pkt); ldns_rr_list_deep_free(rrsigs); ldns_rr_list_deep_free(rrdata); ldns_resolver_deep_free(ldns_res); return result; } void freerrset(struct rrsetinfo *rrset) { u_int16_t i; if (rrset == NULL) return; if (rrset->rri_rdatas) { for (i = 0; i < rrset->rri_nrdatas; i++) { if (rrset->rri_rdatas[i].rdi_data == NULL) break; free(rrset->rri_rdatas[i].rdi_data); } free(rrset->rri_rdatas); } if (rrset->rri_sigs) { for (i = 0; i < rrset->rri_nsigs; i++) { if (rrset->rri_sigs[i].rdi_data == NULL) break; free(rrset->rri_sigs[i].rdi_data); } free(rrset->rri_sigs); } if (rrset->rri_name) free(rrset->rri_name); free(rrset); } #endif /* !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) */ openssh-7.2p2/openbsd-compat/getrrsetbyname.c010064400017500001750000000330741267006270000175730ustar00djmdjm/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */ /* * Copyright (c) 2001 Jakob Schlyter. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright (c) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ #include "includes.h" #if !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) #include #include #include #include #include "getrrsetbyname.h" #if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO extern int h_errno; #endif /* We don't need multithread support here */ #ifdef _THREAD_PRIVATE # undef _THREAD_PRIVATE #endif #define _THREAD_PRIVATE(a,b,c) (c) #ifndef HAVE__RES_EXTERN struct __res_state _res; #endif /* Necessary functions and macros */ /* * Inline versions of get/put short/long. Pointer is advanced. * * These macros demonstrate the property of C whereby it can be * portable or it can be elegant but rarely both. */ #ifndef INT32SZ # define INT32SZ 4 #endif #ifndef INT16SZ # define INT16SZ 2 #endif #ifndef GETSHORT #define GETSHORT(s, cp) { \ register u_char *t_cp = (u_char *)(cp); \ (s) = ((u_int16_t)t_cp[0] << 8) \ | ((u_int16_t)t_cp[1]) \ ; \ (cp) += INT16SZ; \ } #endif #ifndef GETLONG #define GETLONG(l, cp) { \ register u_char *t_cp = (u_char *)(cp); \ (l) = ((u_int32_t)t_cp[0] << 24) \ | ((u_int32_t)t_cp[1] << 16) \ | ((u_int32_t)t_cp[2] << 8) \ | ((u_int32_t)t_cp[3]) \ ; \ (cp) += INT32SZ; \ } #endif /* * Routines to insert/extract short/long's. */ #ifndef HAVE__GETSHORT static u_int16_t _getshort(msgp) register const u_char *msgp; { register u_int16_t u; GETSHORT(u, msgp); return (u); } #elif defined(HAVE_DECL__GETSHORT) && (HAVE_DECL__GETSHORT == 0) u_int16_t _getshort(register const u_char *); #endif #ifndef HAVE__GETLONG static u_int32_t _getlong(msgp) register const u_char *msgp; { register u_int32_t u; GETLONG(u, msgp); return (u); } #elif defined(HAVE_DECL__GETLONG) && (HAVE_DECL__GETLONG == 0) u_int32_t _getlong(register const u_char *); #endif /* ************** */ #define ANSWER_BUFFER_SIZE 0xffff struct dns_query { char *name; u_int16_t type; u_int16_t class; struct dns_query *next; }; struct dns_rr { char *name; u_int16_t type; u_int16_t class; u_int16_t ttl; u_int16_t size; void *rdata; struct dns_rr *next; }; struct dns_response { HEADER header; struct dns_query *query; struct dns_rr *answer; struct dns_rr *authority; struct dns_rr *additional; }; static struct dns_response *parse_dns_response(const u_char *, int); static struct dns_query *parse_dns_qsection(const u_char *, int, const u_char **, int); static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, int); static void free_dns_query(struct dns_query *); static void free_dns_rr(struct dns_rr *); static void free_dns_response(struct dns_response *); static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); int getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); int result; struct rrsetinfo *rrset = NULL; struct dns_response *response = NULL; struct dns_rr *rr; struct rdatainfo *rdata; int length; unsigned int index_ans, index_sig; u_char answer[ANSWER_BUFFER_SIZE]; /* check for invalid class and type */ if (rdclass > 0xffff || rdtype > 0xffff) { result = ERRSET_INVAL; goto fail; } /* don't allow queries of class or type ANY */ if (rdclass == 0xff || rdtype == 0xff) { result = ERRSET_INVAL; goto fail; } /* don't allow flags yet, unimplemented */ if (flags) { result = ERRSET_INVAL; goto fail; } /* initialize resolver */ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { result = ERRSET_FAIL; goto fail; } #ifdef DEBUG _resp->options |= RES_DEBUG; #endif /* DEBUG */ #ifdef RES_USE_DNSSEC /* turn on DNSSEC if EDNS0 is configured */ if (_resp->options & RES_USE_EDNS0) _resp->options |= RES_USE_DNSSEC; #endif /* RES_USE_DNSEC */ /* make query */ length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, answer, sizeof(answer)); if (length < 0) { switch(h_errno) { case HOST_NOT_FOUND: result = ERRSET_NONAME; goto fail; case NO_DATA: result = ERRSET_NODATA; goto fail; default: result = ERRSET_FAIL; goto fail; } } /* parse result */ response = parse_dns_response(answer, length); if (response == NULL) { result = ERRSET_FAIL; goto fail; } if (response->header.qdcount != 1) { result = ERRSET_FAIL; goto fail; } /* initialize rrset */ rrset = calloc(1, sizeof(struct rrsetinfo)); if (rrset == NULL) { result = ERRSET_NOMEMORY; goto fail; } rrset->rri_rdclass = response->query->class; rrset->rri_rdtype = response->query->type; rrset->rri_ttl = response->answer->ttl; rrset->rri_nrdatas = response->header.ancount; #ifdef HAVE_HEADER_AD /* check for authenticated data */ if (response->header.ad == 1) rrset->rri_flags |= RRSET_VALIDATED; #endif /* copy name from answer section */ rrset->rri_name = strdup(response->answer->name); if (rrset->rri_name == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* count answers */ rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, rrset->rri_rdtype); rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, T_RRSIG); /* allocate memory for answers */ rrset->rri_rdatas = calloc(rrset->rri_nrdatas, sizeof(struct rdatainfo)); if (rrset->rri_rdatas == NULL) { result = ERRSET_NOMEMORY; goto fail; } /* allocate memory for signatures */ if (rrset->rri_nsigs > 0) { rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } } /* copy answers & signatures */ for (rr = response->answer, index_ans = 0, index_sig = 0; rr; rr = rr->next) { rdata = NULL; if (rr->class == rrset->rri_rdclass && rr->type == rrset->rri_rdtype) rdata = &rrset->rri_rdatas[index_ans++]; if (rr->class == rrset->rri_rdclass && rr->type == T_RRSIG) rdata = &rrset->rri_sigs[index_sig++]; if (rdata) { rdata->rdi_length = rr->size; rdata->rdi_data = malloc(rr->size); if (rdata->rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } memcpy(rdata->rdi_data, rr->rdata, rr->size); } } free_dns_response(response); *res = rrset; return (ERRSET_SUCCESS); fail: if (rrset != NULL) freerrset(rrset); if (response != NULL) free_dns_response(response); return (result); } void freerrset(struct rrsetinfo *rrset) { u_int16_t i; if (rrset == NULL) return; if (rrset->rri_rdatas) { for (i = 0; i < rrset->rri_nrdatas; i++) { if (rrset->rri_rdatas[i].rdi_data == NULL) break; free(rrset->rri_rdatas[i].rdi_data); } free(rrset->rri_rdatas); } if (rrset->rri_sigs) { for (i = 0; i < rrset->rri_nsigs; i++) { if (rrset->rri_sigs[i].rdi_data == NULL) break; free(rrset->rri_sigs[i].rdi_data); } free(rrset->rri_sigs); } if (rrset->rri_name) free(rrset->rri_name); free(rrset); } /* * DNS response parsing routines */ static struct dns_response * parse_dns_response(const u_char *answer, int size) { struct dns_response *resp; const u_char *cp; /* allocate memory for the response */ resp = calloc(1, sizeof(*resp)); if (resp == NULL) return (NULL); /* initialize current pointer */ cp = answer; /* copy header */ memcpy(&resp->header, cp, HFIXEDSZ); cp += HFIXEDSZ; /* fix header byte order */ resp->header.qdcount = ntohs(resp->header.qdcount); resp->header.ancount = ntohs(resp->header.ancount); resp->header.nscount = ntohs(resp->header.nscount); resp->header.arcount = ntohs(resp->header.arcount); /* there must be at least one query */ if (resp->header.qdcount < 1) { free_dns_response(resp); return (NULL); } /* parse query section */ resp->query = parse_dns_qsection(answer, size, &cp, resp->header.qdcount); if (resp->header.qdcount && resp->query == NULL) { free_dns_response(resp); return (NULL); } /* parse answer section */ resp->answer = parse_dns_rrsection(answer, size, &cp, resp->header.ancount); if (resp->header.ancount && resp->answer == NULL) { free_dns_response(resp); return (NULL); } /* parse authority section */ resp->authority = parse_dns_rrsection(answer, size, &cp, resp->header.nscount); if (resp->header.nscount && resp->authority == NULL) { free_dns_response(resp); return (NULL); } /* parse additional section */ resp->additional = parse_dns_rrsection(answer, size, &cp, resp->header.arcount); if (resp->header.arcount && resp->additional == NULL) { free_dns_response(resp); return (NULL); } return (resp); } static struct dns_query * parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) { struct dns_query *head, *curr, *prev; int i, length; char name[MAXDNAME]; for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { /* allocate and initialize struct */ curr = calloc(1, sizeof(struct dns_query)); if (curr == NULL) { free_dns_query(head); return (NULL); } if (head == NULL) head = curr; if (prev != NULL) prev->next = curr; /* name */ length = dn_expand(answer, answer + size, *cp, name, sizeof(name)); if (length < 0) { free_dns_query(head); return (NULL); } curr->name = strdup(name); if (curr->name == NULL) { free_dns_query(head); return (NULL); } *cp += length; /* type */ curr->type = _getshort(*cp); *cp += INT16SZ; /* class */ curr->class = _getshort(*cp); *cp += INT16SZ; } return (head); } static struct dns_rr * parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) { struct dns_rr *head, *curr, *prev; int i, length; char name[MAXDNAME]; for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { /* allocate and initialize struct */ curr = calloc(1, sizeof(struct dns_rr)); if (curr == NULL) { free_dns_rr(head); return (NULL); } if (head == NULL) head = curr; if (prev != NULL) prev->next = curr; /* name */ length = dn_expand(answer, answer + size, *cp, name, sizeof(name)); if (length < 0) { free_dns_rr(head); return (NULL); } curr->name = strdup(name); if (curr->name == NULL) { free_dns_rr(head); return (NULL); } *cp += length; /* type */ curr->type = _getshort(*cp); *cp += INT16SZ; /* class */ curr->class = _getshort(*cp); *cp += INT16SZ; /* ttl */ curr->ttl = _getlong(*cp); *cp += INT32SZ; /* rdata size */ curr->size = _getshort(*cp); *cp += INT16SZ; /* rdata itself */ curr->rdata = malloc(curr->size); if (curr->rdata == NULL) { free_dns_rr(head); return (NULL); } memcpy(curr->rdata, *cp, curr->size); *cp += curr->size; } return (head); } static void free_dns_query(struct dns_query *p) { if (p == NULL) return; if (p->name) free(p->name); free_dns_query(p->next); free(p); } static void free_dns_rr(struct dns_rr *p) { if (p == NULL) return; if (p->name) free(p->name); if (p->rdata) free(p->rdata); free_dns_rr(p->next); free(p); } static void free_dns_response(struct dns_response *p) { if (p == NULL) return; free_dns_query(p->query); free_dns_rr(p->answer); free_dns_rr(p->authority); free_dns_rr(p->additional); free(p); } static int count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) { int n = 0; while(p) { if (p->class == class && p->type == type) n++; p = p->next; } return (n); } #endif /* !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) */ openssh-7.2p2/openbsd-compat/getrrsetbyname.h010064400017500001750000000071741267006270000176020ustar00djmdjm/* OPENBSD BASED ON : include/netdb.h */ /* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */ /* * Copyright (c) 2001 Jakob Schlyter. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright (c) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _GETRRSETBYNAME_H #define _GETRRSETBYNAME_H #include "includes.h" #ifndef HAVE_GETRRSETBYNAME #include #include #include #include #include #ifndef HFIXEDSZ #define HFIXEDSZ 12 #endif #ifndef T_RRSIG #define T_RRSIG 46 #endif /* * Flags for getrrsetbyname() */ #ifndef RRSET_VALIDATED # define RRSET_VALIDATED 1 #endif /* * Return codes for getrrsetbyname() */ #ifndef ERRSET_SUCCESS # define ERRSET_SUCCESS 0 # define ERRSET_NOMEMORY 1 # define ERRSET_FAIL 2 # define ERRSET_INVAL 3 # define ERRSET_NONAME 4 # define ERRSET_NODATA 5 #endif struct rdatainfo { unsigned int rdi_length; /* length of data */ unsigned char *rdi_data; /* record data */ }; struct rrsetinfo { unsigned int rri_flags; /* RRSET_VALIDATED ... */ unsigned int rri_rdclass; /* class number */ unsigned int rri_rdtype; /* RR type number */ unsigned int rri_ttl; /* time to live */ unsigned int rri_nrdatas; /* size of rdatas array */ unsigned int rri_nsigs; /* size of sigs array */ char *rri_name; /* canonical name */ struct rdatainfo *rri_rdatas; /* individual records */ struct rdatainfo *rri_sigs; /* individual signatures */ }; int getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); void freerrset(struct rrsetinfo *); #endif /* !defined(HAVE_GETRRSETBYNAME) */ #endif /* _GETRRSETBYNAME_H */ openssh-7.2p2/openbsd-compat/glob.h010064400017500001750000000110521267006270000154600ustar00djmdjm/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */ /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * 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. * * @(#)glob.h 8.1 (Berkeley) 6/2/93 */ /* OPENBSD ORIGINAL: include/glob.h */ #if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \ !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ defined(BROKEN_GLOB) #ifndef _COMPAT_GLOB_H_ #define _COMPAT_GLOB_H_ #include # define glob_t _ssh_compat_glob_t # define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d) # define globfree(a) _ssh__compat_globfree(a) struct stat; typedef struct { int gl_pathc; /* Count of total paths so far. */ int gl_matchc; /* Count of paths matching pattern. */ int gl_offs; /* Reserved at beginning of gl_pathv. */ int gl_flags; /* Copy of flags parameter to glob. */ char **gl_pathv; /* List of paths matching pattern. */ struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */ /* Copy of errfunc parameter to glob. */ int (*gl_errfunc)(const char *, int); /* * Alternate filesystem access methods for glob; replacement * versions of closedir(3), readdir(3), opendir(3), stat(2) * and lstat(2). */ void (*gl_closedir)(void *); struct dirent *(*gl_readdir)(void *); void *(*gl_opendir)(const char *); int (*gl_lstat)(const char *, struct stat *); int (*gl_stat)(const char *, struct stat *); } glob_t; #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ #define GLOB_ERR 0x0004 /* Return on error. */ #define GLOB_MARK 0x0008 /* Append / to matching directories. */ #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ #define GLOB_NOSORT 0x0020 /* Don't sort. */ #define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ #define GLOB_NOSPACE (-1) /* Malloc call failed. */ #define GLOB_ABORTED (-2) /* Unignored error. */ #define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ #define GLOB_NOSYS (-4) /* Function not supported. */ #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ #define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ #define GLOB_KEEPSTAT 0x4000 /* Retain stat data for paths in gl_statv. */ #define GLOB_ABEND GLOB_ABORTED /* backward compatibility */ int glob(const char *, int, int (*)(const char *, int), glob_t *); void globfree(glob_t *); #endif /* !_GLOB_H_ */ #endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOH_HAS_GL_STATV) */ openssh-7.2p2/openbsd-compat/inet_aton.c010064400017500001750000000123551267006270000165170ustar00djmdjm/* $OpenBSD: inet_addr.c,v 1.9 2005/08/06 20:30:03 espie Exp $ */ /* * Copyright (c) 1983, 1990, 1993 * 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. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * 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, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION 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. * - * --Copyright-- */ /* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */ #include "includes.h" #if !defined(HAVE_INET_ATON) #include #include #include #include #include #if 0 /* * Ascii internet address interpretation routine. * The value returned is in network order. */ in_addr_t inet_addr(const char *cp) { struct in_addr val; if (inet_aton(cp, &val)) return (val.s_addr); return (INADDR_NONE); } #endif /* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. */ int inet_aton(const char *cp, struct in_addr *addr) { u_int32_t val; int base, n; char c; u_int parts[4]; u_int *pp = parts; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ if (!isdigit(c)) return (0); val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; else base = 8; } for (;;) { if (isascii(c) && isdigit(c)) { val = (val * base) + (c - '0'); c = *++cp; } else if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3) return (0); *pp++ = val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && (!isascii(c) || !isspace(c))) return (0); /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 0: return (0); /* initial nondigit */ case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if ((val > 0xffffff) || (parts[0] > 0xff)) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr) addr->s_addr = htonl(val); return (1); } #endif /* !defined(HAVE_INET_ATON) */ openssh-7.2p2/openbsd-compat/inet_ntoa.c010064400017500001750000000043271267006270000165170ustar00djmdjm/* $OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ /* * Copyright (c) 1983, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/net/inet_ntoa.c */ #include "includes.h" #if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) /* * Convert network-format internet address * to base 256 d.d.d.d representation. */ #include #include #include #include char * inet_ntoa(struct in_addr in) { static char b[18]; char *p; p = (char *)∈ #define UC(b) (((int)b)&0xff) (void)snprintf(b, sizeof(b), "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); return (b); } #endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ openssh-7.2p2/openbsd-compat/inet_ntop.c010064400017500001750000000126621267006270000165370ustar00djmdjm/* $OpenBSD: inet_ntop.c,v 1.8 2008/12/09 19:38:38 otto Exp $ */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/net/inet_ntop.c */ #include "includes.h" #ifndef HAVE_INET_NTOP #include #include #include #include #include #include #include #include #include #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 /* IPv6 T_AAAA */ #endif #ifndef INT16SZ #define INT16SZ 2 /* for systems without 16-bit ints */ #endif /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const u_char *src, char *dst, size_t size); static const char *inet_ntop6(const u_char *src, char *dst, size_t size); /* char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * inet_ntop(int af, const void *src, char *dst, socklen_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, (size_t)size)); case AF_INET6: return (inet_ntop6(src, dst, (size_t)size)); default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const u_char *src, char *dst, size_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; int l; l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); if (l <= 0 || l >= size) { errno = ENOSPC; return (NULL); } strlcpy(dst, tmp, size); return (dst); } /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(const u_char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; char *tp, *ep; struct { int base, len; } best, cur; u_int words[IN6ADDRSZ / INT16SZ]; int i; int advance; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; ep = tmp + sizeof(tmp); for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) return (NULL); tp += strlen(tp); break; } advance = snprintf(tp, ep - tp, "%x", words[i]); if (advance <= 0 || advance >= ep - tp) return (NULL); tp += advance; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } if (tp + 1 >= ep) return (NULL); *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strlcpy(dst, tmp, size); return (dst); } #endif /* !HAVE_INET_NTOP */ openssh-7.2p2/openbsd-compat/kludge-fd_set.c010064400017500001750000000015621267006270000172520ustar00djmdjm/* Placed in the public domain. */ /* * _FORTIFY_SOURCE includes a misguided check for FD_SET(n)/FD_ISSET(b) * where n > FD_SETSIZE. This breaks OpenSSH and other programs that * explicitly allocate fd_sets. To avoid this, we wrap FD_SET in a * function compiled without _FORTIFY_SOURCE. */ #include "config.h" #if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE) # include # if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) # undef _FORTIFY_SOURCE # undef __USE_FORTIFY_LEVEL # include void kludge_FD_SET(int n, fd_set *set) { FD_SET(n, set); } int kludge_FD_ISSET(int n, fd_set *set) { return FD_ISSET(n, set); } # endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */ # endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */ #endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */ openssh-7.2p2/openbsd-compat/md5.c010064400017500001750000000175161267006270000152300ustar00djmdjm/* $OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $ */ /* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. */ #include "includes.h" #ifndef WITH_OPENSSL #include #include #include "md5.h" #define PUT_64BIT_LE(cp, value) do { \ (cp)[7] = (value) >> 56; \ (cp)[6] = (value) >> 48; \ (cp)[5] = (value) >> 40; \ (cp)[4] = (value) >> 32; \ (cp)[3] = (value) >> 24; \ (cp)[2] = (value) >> 16; \ (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) #define PUT_32BIT_LE(cp, value) do { \ (cp)[3] = (value) >> 24; \ (cp)[2] = (value) >> 16; \ (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(MD5_CTX *ctx) { ctx->count = 0; ctx->state[0] = 0x67452301; ctx->state[1] = 0xefcdab89; ctx->state[2] = 0x98badcfe; ctx->state[3] = 0x10325476; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) { size_t have, need; /* Check how many bytes we already have and how many more we need. */ have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); need = MD5_BLOCK_LENGTH - have; /* Update bitcount */ ctx->count += (u_int64_t)len << 3; if (len >= need) { if (have != 0) { memcpy(ctx->buffer + have, input, need); MD5Transform(ctx->state, ctx->buffer); input += need; len -= need; have = 0; } /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ while (len >= MD5_BLOCK_LENGTH) { MD5Transform(ctx->state, input); input += MD5_BLOCK_LENGTH; len -= MD5_BLOCK_LENGTH; } } /* Handle any remaining bytes of data. */ if (len != 0) memcpy(ctx->buffer + have, input, len); } /* * Pad pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Pad(MD5_CTX *ctx) { u_int8_t count[8]; size_t padlen; /* Convert count to 8 bytes in little endian order. */ PUT_64BIT_LE(count, ctx->count); /* Pad out to 56 mod 64. */ padlen = MD5_BLOCK_LENGTH - ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); if (padlen < 1 + 8) padlen += MD5_BLOCK_LENGTH; MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ MD5Update(ctx, count, 8); } /* * Final wrapup--call MD5Pad, fill in digest and zero out ctx. */ void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) { int i; MD5Pad(ctx); for (i = 0; i < 4; i++) PUT_32BIT_LE(digest + i * 4, ctx->state[i]); memset(ctx, 0, sizeof(*ctx)); } /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ void MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) { u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; #if BYTE_ORDER == LITTLE_ENDIAN memcpy(in, block, sizeof(in)); #else for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { in[a] = (u_int32_t)( (u_int32_t)(block[a * 4 + 0]) | (u_int32_t)(block[a * 4 + 1]) << 8 | (u_int32_t)(block[a * 4 + 2]) << 16 | (u_int32_t)(block[a * 4 + 3]) << 24); } #endif a = state[0]; b = state[1]; c = state[2]; d = state[3]; MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } #endif /* !WITH_OPENSSL */ openssh-7.2p2/openbsd-compat/md5.h010064400017500001750000000035431267006270000152300ustar00djmdjm/* $OpenBSD: md5.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ /* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. */ #ifndef _MD5_H_ #define _MD5_H_ #ifndef WITH_OPENSSL #define MD5_BLOCK_LENGTH 64 #define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) typedef struct MD5Context { u_int32_t state[4]; /* state */ u_int64_t count; /* number of bits, mod 2^64 */ u_int8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */ } MD5_CTX; void MD5Init(MD5_CTX *); void MD5Update(MD5_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void MD5Pad(MD5_CTX *); void MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *) __attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH))); void MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]) __attribute__((__bounded__(__minbytes__,1,4))) __attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH))); char *MD5End(MD5_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); char *MD5File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); char *MD5FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); char *MD5Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,MD5_DIGEST_STRING_LENGTH))); #endif /* !WITH_OPENSSL */ #endif /* _MD5_H_ */ openssh-7.2p2/openbsd-compat/mktemp.c010064400017500001750000000062201267006270000160260ustar00djmdjm/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ /* Changes: Removed mktemp */ /* $OpenBSD: mktemp.c,v 1.30 2010/03/21 23:09:30 schwarze Exp $ */ /* * Copyright (c) 1996-1998, 2008 Theo de Raadt * Copyright (c) 1997, 2008-2009 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/stdio/mktemp.c */ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) #define MKTEMP_NAME 0 #define MKTEMP_FILE 1 #define MKTEMP_DIR 2 #define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" #define NUM_CHARS (sizeof(TEMPCHARS) - 1) static int mktemp_internal(char *path, int slen, int mode) { char *start, *cp, *ep; const char *tempchars = TEMPCHARS; unsigned int r, tries; struct stat sb; size_t len; int fd; len = strlen(path); if (len == 0 || slen < 0 || (size_t)slen >= len) { errno = EINVAL; return(-1); } ep = path + len - slen; tries = 1; for (start = ep; start > path && start[-1] == 'X'; start--) { if (tries < INT_MAX / NUM_CHARS) tries *= NUM_CHARS; } tries *= 2; do { for (cp = start; cp != ep; cp++) { r = arc4random_uniform(NUM_CHARS); *cp = tempchars[r]; } switch (mode) { case MKTEMP_NAME: if (lstat(path, &sb) != 0) return(errno == ENOENT ? 0 : -1); break; case MKTEMP_FILE: fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); if (fd != -1 || errno != EEXIST) return(fd); break; case MKTEMP_DIR: if (mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR) == 0) return(0); if (errno != EEXIST) return(-1); break; } } while (--tries); errno = EEXIST; return(-1); } #if 0 char *_mktemp(char *); char * _mktemp(char *path) { if (mktemp_internal(path, 0, MKTEMP_NAME) == -1) return(NULL); return(path); } __warn_references(mktemp, "warning: mktemp() possibly used unsafely; consider using mkstemp()"); char * mktemp(char *path) { return(_mktemp(path)); } #endif int mkstemp(char *path) { return(mktemp_internal(path, 0, MKTEMP_FILE)); } int mkstemps(char *path, int slen) { return(mktemp_internal(path, slen, MKTEMP_FILE)); } char * mkdtemp(char *path) { int error; error = mktemp_internal(path, 0, MKTEMP_DIR); return(error ? NULL : path); } #endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */ openssh-7.2p2/openbsd-compat/openbsd-compat.h010064400017500001750000000171431267006270000174570ustar00djmdjm/* $Id: openbsd-compat.h,v 1.62 2014/09/30 23:43:08 djm Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. * Copyright (c) 2003 Ben Lindstrom. All rights reserved. * Copyright (c) 2002 Tim Rice. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _OPENBSD_COMPAT_H #define _OPENBSD_COMPAT_H #include "includes.h" #include #include #include /* OpenBSD function replacements */ #include "base64.h" #include "sigact.h" #include "readpassphrase.h" #include "vis.h" #include "getrrsetbyname.h" #include "sha1.h" #include "sha2.h" #include "rmd160.h" #include "md5.h" #include "blf.h" #ifndef HAVE_BASENAME char *basename(const char *path); #endif #ifndef HAVE_BINDRESVPORT_SA int bindresvport_sa(int sd, struct sockaddr *sa); #endif #ifndef HAVE_CLOSEFROM void closefrom(int); #endif #ifndef HAVE_GETCWD char *getcwd(char *pt, size_t size); #endif #ifndef HAVE_REALLOCARRAY void *reallocarray(void *, size_t, size_t); #endif #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) /* * glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the * compat version. */ # ifdef BROKEN_REALPATH # define realpath(x, y) _ssh_compat_realpath(x, y) # endif char *realpath(const char *path, char *resolved); #endif #ifndef HAVE_RRESVPORT_AF int rresvport_af(int *alport, sa_family_t af); #endif #ifndef HAVE_STRLCPY /* #include XXX Still needed? */ size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRLCAT /* #include XXX Still needed? */ size_t strlcat(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_SETENV int setenv(register const char *name, register const char *value, int rewrite); #endif #ifndef HAVE_STRMODE void strmode(int mode, char *p); #endif #ifndef HAVE_STRPTIME #include char *strptime(const char *buf, const char *fmt, struct tm *tm); #endif #if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) int mkstemps(char *path, int slen); int mkstemp(char *path); char *mkdtemp(char *path); #endif #ifndef HAVE_DAEMON int daemon(int nochdir, int noclose); #endif #ifndef HAVE_DIRNAME char *dirname(const char *path); #endif #ifndef HAVE_FMT_SCALED #define FMT_SCALED_STRSIZE 7 int fmt_scaled(long long number, char *result); #endif #ifndef HAVE_SCAN_SCALED int scan_scaled(char *, long long *); #endif #if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) char *inet_ntoa(struct in_addr in); #endif #ifndef HAVE_INET_NTOP const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #ifndef HAVE_INET_ATON int inet_aton(const char *cp, struct in_addr *addr); #endif #ifndef HAVE_STRSEP char *strsep(char **stringp, const char *delim); #endif #ifndef HAVE_SETPROCTITLE void setproctitle(const char *fmt, ...); void compat_init_setproctitle(int argc, char *argv[]); #endif #ifndef HAVE_GETGROUPLIST /* #include XXXX Still needed ? */ int getgrouplist(const char *, gid_t, gid_t *, int *); #endif #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) int BSDgetopt(int argc, char * const *argv, const char *opts); #include "openbsd-compat/getopt.h" #endif #if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0 # include # include int writev(int, struct iovec *, int); #endif /* Home grown routines */ #include "bsd-misc.h" #include "bsd-setres_id.h" #include "bsd-statvfs.h" #include "bsd-waitpid.h" #include "bsd-poll.h" #ifndef HAVE_GETPEEREID int getpeereid(int , uid_t *, gid_t *); #endif #ifdef HAVE_ARC4RANDOM # ifndef HAVE_ARC4RANDOM_STIR # define arc4random_stir() # endif #else unsigned int arc4random(void); void arc4random_stir(void); #endif /* !HAVE_ARC4RANDOM */ #ifndef HAVE_ARC4RANDOM_BUF void arc4random_buf(void *, size_t); #endif #ifndef HAVE_ARC4RANDOM_UNIFORM u_int32_t arc4random_uniform(u_int32_t); #endif #ifndef HAVE_ASPRINTF int asprintf(char **, const char *, ...); #endif #ifndef HAVE_OPENPTY # include /* for struct winsize */ int openpty(int *, int *, char *, struct termios *, struct winsize *); #endif /* HAVE_OPENPTY */ /* #include XXX needed? For size_t */ #ifndef HAVE_SNPRINTF int snprintf(char *, size_t, SNPRINTF_CONST char *, ...); #endif #ifndef HAVE_STRTOLL long long strtoll(const char *, char **, int); #endif #ifndef HAVE_STRTOUL unsigned long strtoul(const char *, char **, int); #endif #ifndef HAVE_STRTOULL unsigned long long strtoull(const char *, char **, int); #endif #ifndef HAVE_STRTONUM long long strtonum(const char *, long long, long long, const char **); #endif /* multibyte character support */ #ifndef HAVE_MBLEN # define mblen(x, y) (1) #endif #if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF) # include #endif #ifndef HAVE_VASPRINTF int vasprintf(char **, const char *, va_list); #endif #ifndef HAVE_VSNPRINTF int vsnprintf(char *, size_t, const char *, va_list); #endif #ifndef HAVE_USER_FROM_UID char *user_from_uid(uid_t, int); #endif #ifndef HAVE_GROUP_FROM_GID char *group_from_gid(gid_t, int); #endif #ifndef HAVE_TIMINGSAFE_BCMP int timingsafe_bcmp(const void *, const void *, size_t); #endif #ifndef HAVE_BCRYPT_PBKDF int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, u_int8_t *, size_t, unsigned int); #endif #ifndef HAVE_EXPLICIT_BZERO void explicit_bzero(void *p, size_t n); #endif void *xmmap(size_t size); char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); /* rfc2553 socket API replacements */ #include "fake-rfc2553.h" /* Routines for a single OS platform */ #include "bsd-cray.h" #include "bsd-cygwin_util.h" #include "port-aix.h" #include "port-irix.h" #include "port-linux.h" #include "port-solaris.h" #include "port-tun.h" #include "port-uw.h" /* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */ #if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE) # include # if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) # include /* Ensure include guard is defined */ # undef FD_SET # undef FD_ISSET # define FD_SET(n, set) kludge_FD_SET(n, set) # define FD_ISSET(n, set) kludge_FD_ISSET(n, set) void kludge_FD_SET(int, fd_set *); int kludge_FD_ISSET(int, fd_set *); # endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */ # endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */ #endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */ #endif /* _OPENBSD_COMPAT_H */ openssh-7.2p2/openbsd-compat/openssl-compat.c010064400017500001750000000045201267006270000174760ustar00djmdjm/* $Id: openssl-compat.c,v 1.19 2014/07/02 05:28:07 djm Exp $ */ /* * Copyright (c) 2005 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #define SSH_DONT_OVERLOAD_OPENSSL_FUNCS #include "includes.h" #ifdef WITH_OPENSSL #include #include #ifdef USE_OPENSSL_ENGINE # include # include #endif #include "log.h" #include "openssl-compat.h" /* * OpenSSL version numbers: MNNFFPPS: major minor fix patch status * We match major, minor, fix and status (not patch) for <1.0.0. * After that, we acceptable compatible fix versions (so we * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed * within a patch series. */ int ssh_compatible_openssl(long headerver, long libver) { long mask, hfix, lfix; /* exact match is always OK */ if (headerver == libver) return 1; /* for versions < 1.0.0, major,minor,fix,status must match */ if (headerver < 0x1000000f) { mask = 0xfffff00fL; /* major,minor,fix,status */ return (headerver & mask) == (libver & mask); } /* * For versions >= 1.0.0, major,minor,status must match and library * fix version must be equal to or newer than the header. */ mask = 0xfff0000fL; /* major,minor,status */ hfix = (headerver & 0x000ff000) >> 12; lfix = (libver & 0x000ff000) >> 12; if ( (headerver & mask) == (libver & mask) && lfix >= hfix) return 1; return 0; } #ifdef USE_OPENSSL_ENGINE void ssh_OpenSSL_add_all_algorithms(void) { OpenSSL_add_all_algorithms(); /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); OPENSSL_config(NULL); } #endif #endif /* WITH_OPENSSL */ openssh-7.2p2/openbsd-compat/openssl-compat.h010064400017500001750000000057631267006270000175150ustar00djmdjm/* $Id: openssl-compat.h,v 1.31 2014/08/29 18:18:29 djm Exp $ */ /* * Copyright (c) 2005 Darren Tucker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _OPENSSL_COMPAT_H #define _OPENSSL_COMPAT_H #include "includes.h" #ifdef WITH_OPENSSL #include #include #include #include int ssh_compatible_openssl(long, long); #if (OPENSSL_VERSION_NUMBER <= 0x0090805fL) # error OpenSSL 0.9.8f or greater is required #endif #if OPENSSL_VERSION_NUMBER < 0x10000001L # define LIBCRYPTO_EVP_INL_TYPE unsigned int #else # define LIBCRYPTO_EVP_INL_TYPE size_t #endif #ifndef OPENSSL_RSA_MAX_MODULUS_BITS # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif #ifndef OPENSSL_DSA_MAX_MODULUS_BITS # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif #ifndef OPENSSL_HAVE_EVPCTR # define EVP_aes_128_ctr evp_aes_128_ctr # define EVP_aes_192_ctr evp_aes_128_ctr # define EVP_aes_256_ctr evp_aes_128_ctr const EVP_CIPHER *evp_aes_128_ctr(void); void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); #endif /* Avoid some #ifdef. Code that uses these is unreachable without GCM */ #if !defined(OPENSSL_HAVE_EVPGCM) && !defined(EVP_CTRL_GCM_SET_IV_FIXED) # define EVP_CTRL_GCM_SET_IV_FIXED -1 # define EVP_CTRL_GCM_IV_GEN -1 # define EVP_CTRL_GCM_SET_TAG -1 # define EVP_CTRL_GCM_GET_TAG -1 #endif /* Replace missing EVP_CIPHER_CTX_ctrl() with something that returns failure */ #ifndef HAVE_EVP_CIPHER_CTX_CTRL # ifdef OPENSSL_HAVE_EVPGCM # error AES-GCM enabled without EVP_CIPHER_CTX_ctrl /* shouldn't happen */ # else # define EVP_CIPHER_CTX_ctrl(a,b,c,d) (0) # endif #endif /* * We overload some of the OpenSSL crypto functions with ssh_* equivalents * to automatically handle OpenSSL engine initialisation. * * In order for the compat library to call the real functions, it must * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and * implement the ssh_* equivalents. */ #ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS # ifdef USE_OPENSSL_ENGINE # ifdef OpenSSL_add_all_algorithms # undef OpenSSL_add_all_algorithms # endif # define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms() # endif void ssh_OpenSSL_add_all_algorithms(void); #endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ #endif /* WITH_OPENSSL */ #endif /* _OPENSSL_COMPAT_H */ openssh-7.2p2/openbsd-compat/port-aix.c010064400017500001750000000305671267006270000163070ustar00djmdjm/* * * Copyright (c) 2001 Gert Doering. All rights reserved. * Copyright (c) 2003,2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 "xmalloc.h" #include "buffer.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "ssh.h" #include "log.h" #ifdef _AIX #include #if defined(HAVE_NETDB_H) # include #endif #include #include #include #include #include #ifdef WITH_AIXAUTHENTICATE # include # include # if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG) # include # endif # include #endif #include "port-aix.h" static char *lastlogin_msg = NULL; # ifdef HAVE_SETAUTHDB static char old_registry[REGISTRY_SIZE] = ""; # endif /* * AIX has a "usrinfo" area where logname and other stuff is stored - * a few applications actually use this and die if it's not set * * NOTE: TTY= should be set, but since no one uses it and it's hard to * acquire due to privsep code. We will just drop support. */ void aix_usrinfo(struct passwd *pw) { u_int i; size_t len; char *cp; len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); cp = xmalloc(len); i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', pw->pw_name, '\0'); if (usrinfo(SETUINFO, cp, i) == -1) fatal("Couldn't set usrinfo: %s", strerror(errno)); debug3("AIX/UsrInfo: set len %d", i); free(cp); } # ifdef WITH_AIXAUTHENTICATE /* * Remove embedded newlines in string (if any). * Used before logging messages returned by AIX authentication functions * so the message is logged on one line. */ void aix_remove_embedded_newlines(char *p) { if (p == NULL) return; for (; *p; p++) { if (*p == '\n') *p = ' '; } /* Remove trailing whitespace */ if (*--p == ' ') *p = '\0'; } /* * Test specifically for the case where SYSTEM == NONE and AUTH1 contains * anything other than NONE or SYSTEM, which indicates that the admin has * configured the account for purely AUTH1-type authentication. * * Since authenticate() doesn't check AUTH1, and sshd can't sanely support * AUTH1 itself, in such a case authenticate() will allow access without * authentation, which is almost certainly not what the admin intends. * * (The native tools, eg login, will process the AUTH1 list in addition to * the SYSTEM list by using ckuserID(), however ckuserID() and AUTH1 methods * have been deprecated since AIX 4.2.x and would be very difficult for sshd * to support. * * Returns 0 if an unsupportable combination is found, 1 otherwise. */ static int aix_valid_authentications(const char *user) { char *auth1, *sys, *p; int valid = 1; if (getuserattr((char *)user, S_AUTHSYSTEM, &sys, SEC_CHAR) != 0) { logit("Can't retrieve attribute SYSTEM for %s: %.100s", user, strerror(errno)); return 0; } debug3("AIX SYSTEM attribute %s", sys); if (strcmp(sys, "NONE") != 0) return 1; /* not "NONE", so is OK */ if (getuserattr((char *)user, S_AUTH1, &auth1, SEC_LIST) != 0) { logit("Can't retrieve attribute auth1 for %s: %.100s", user, strerror(errno)); return 0; } p = auth1; /* A SEC_LIST is concatenated strings, ending with two NULs. */ while (p[0] != '\0' && p[1] != '\0') { debug3("AIX auth1 attribute list member %s", p); if (strcmp(p, "NONE") != 0 && strcmp(p, "SYSTEM")) { logit("Account %s has unsupported auth1 value '%s'", user, p); valid = 0; } p += strlen(p) + 1; } return (valid); } /* * Do authentication via AIX's authenticate routine. We loop until the * reenter parameter is 0, but normally authenticate is called only once. * * Note: this function returns 1 on success, whereas AIX's authenticate() * returns 0. */ int sys_auth_passwd(Authctxt *ctxt, const char *password) { char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; int authsuccess = 0, expired, reenter, result; do { result = authenticate((char *)name, (char *)password, &reenter, &authmsg); aix_remove_embedded_newlines(authmsg); debug3("AIX/authenticate result %d, authmsg %.100s", result, authmsg); } while (reenter); if (!aix_valid_authentications(name)) result = -1; if (result == 0) { authsuccess = 1; /* * Record successful login. We don't have a pty yet, so just * label the line as "ssh" */ aix_setauthdb(name); /* * Check if the user's password is expired. */ expired = passwdexpired(name, &msg); if (msg && *msg) { buffer_append(ctxt->loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); } debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); switch (expired) { case 0: /* password not expired */ break; case 1: /* expired, password change required */ ctxt->force_pwchange = 1; break; default: /* user can't change(2) or other error (-1) */ logit("Password can't be changed for user %s: %.100s", name, msg); free(msg); authsuccess = 0; } aix_restoreauthdb(); } free(authmsg); return authsuccess; } /* * Check if specified account is permitted to log in. * Returns 1 if login is allowed, 0 if not allowed. */ int sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) { char *msg = NULL; int result, permitted = 0; struct stat st; /* * Don't perform checks for root account (PermitRootLogin controls * logins via ssh) or if running as non-root user (since * loginrestrictions will always fail due to insufficient privilege). */ if (pw->pw_uid == 0 || geteuid() != 0) { debug3("%s: not checking", __func__); return 1; } result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); if (result == 0) permitted = 1; /* * If restricted because /etc/nologin exists, the login will be denied * in session.c after the nologin message is sent, so allow for now * and do not append the returned message. */ if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) permitted = 1; else if (msg != NULL) buffer_append(loginmsg, msg, strlen(msg)); if (msg == NULL) msg = xstrdup("(none)"); aix_remove_embedded_newlines(msg); debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); if (!permitted) logit("Login restricted for %s: %.100s", pw->pw_name, msg); free(msg); return permitted; } int sys_auth_record_login(const char *user, const char *host, const char *ttynm, Buffer *loginmsg) { char *msg = NULL; int success = 0; aix_setauthdb(user); if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) { success = 1; if (msg != NULL) { debug("AIX/loginsuccess: msg %s", msg); if (lastlogin_msg == NULL) lastlogin_msg = msg; } } aix_restoreauthdb(); return (success); } char * sys_auth_get_lastlogin_msg(const char *user, uid_t uid) { char *msg = lastlogin_msg; lastlogin_msg = NULL; return msg; } # ifdef CUSTOM_FAILED_LOGIN /* * record_failed_login: generic "login failed" interface function */ void record_failed_login(const char *user, const char *hostname, const char *ttyname) { if (geteuid() != 0) return; aix_setauthdb(user); # ifdef AIX_LOGINFAILED_4ARG loginfailed((char *)user, (char *)hostname, (char *)ttyname, AUDIT_FAIL_AUTH); # else loginfailed((char *)user, (char *)hostname, (char *)ttyname); # endif aix_restoreauthdb(); } # endif /* CUSTOM_FAILED_LOGIN */ /* * If we have setauthdb, retrieve the password registry for the user's * account then feed it to setauthdb. This will mean that subsequent AIX auth * functions will only use the specified loadable module. If we don't have * setauthdb this is a no-op. */ void aix_setauthdb(const char *user) { # ifdef HAVE_SETAUTHDB char *registry; if (setuserdb(S_READ) == -1) { debug3("%s: Could not open userdb to read", __func__); return; } if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { if (setauthdb(registry, old_registry) == 0) debug3("AIX/setauthdb set registry '%s'", registry); else debug3("AIX/setauthdb set registry '%s' failed: %s", registry, strerror(errno)); } else debug3("%s: Could not read S_REGISTRY for user: %s", __func__, strerror(errno)); enduserdb(); # endif /* HAVE_SETAUTHDB */ } /* * Restore the user's registry settings from old_registry. * Note that if the first aix_setauthdb fails, setauthdb("") is still safe * (it restores the system default behaviour). If we don't have setauthdb, * this is a no-op. */ void aix_restoreauthdb(void) { # ifdef HAVE_SETAUTHDB if (setauthdb(old_registry, NULL) == 0) debug3("%s: restoring old registry '%s'", __func__, old_registry); else debug3("%s: failed to restore old registry %s", __func__, old_registry); # endif /* HAVE_SETAUTHDB */ } # endif /* WITH_AIXAUTHENTICATE */ # ifdef USE_AIX_KRB_NAME /* * aix_krb5_get_principal_name: returns the user's kerberos client principal name if * configured, otherwise NULL. Caller must free returned string. */ char * aix_krb5_get_principal_name(char *pw_name) { char *authname = NULL, *authdomain = NULL, *principal = NULL; setuserdb(S_READ); if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0) debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno)); if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0) debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno)); if (authdomain != NULL) xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain); else if (authname != NULL) principal = xstrdup(authname); enduserdb(); return principal; } # endif /* USE_AIX_KRB_NAME */ # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) # undef getnameinfo /* * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros * IPv6 address into its textual representation ("::"), so we wrap it * with a function that will. */ int sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct sockaddr_in6 *sa6; u_int32_t *a6; if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && sa->sa_family == AF_INET6) { sa6 = (struct sockaddr_in6 *)sa; a6 = sa6->sin6_addr.u6_addr.u6_addr32; if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { strlcpy(host, "::", hostlen); snprintf(serv, servlen, "%d", sa6->sin6_port); return 0; } } return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } # endif /* AIX_GETNAMEINFO_HACK */ # if defined(USE_GETGRSET) # include int getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt) { char *cp, *grplist, *grp; gid_t gid; int ret = 0, ngroups = 0, maxgroups; long l; maxgroups = *grpcnt; if ((cp = grplist = getgrset(user)) == NULL) return -1; /* handle zero-length case */ if (maxgroups <= 0) { *grpcnt = 0; return -1; } /* copy primary group */ groups[ngroups++] = pgid; /* copy each entry from getgrset into group list */ while ((grp = strsep(&grplist, ",")) != NULL) { l = strtol(grp, NULL, 10); if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { ret = -1; goto out; } gid = (gid_t)l; if (gid == pgid) continue; /* we have already added primary gid */ groups[ngroups++] = gid; } out: free(cp); *grpcnt = ngroups; return ret; } # endif /* USE_GETGRSET */ #endif /* _AIX */ openssh-7.2p2/openbsd-compat/port-aix.h010064400017500001750000000104231267006270000163010ustar00djmdjm/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */ /* * * Copyright (c) 2001 Gert Doering. All rights reserved. * Copyright (c) 2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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. */ #ifdef _AIX #ifdef HAVE_SYS_SOCKET_H # include #endif #include "buffer.h" /* These should be in the system headers but are not. */ int usrinfo(int, char *, int); #if defined(HAVE_DECL_SETAUTHDB) && (HAVE_DECL_SETAUTHDB == 0) int setauthdb(const char *, char *); #endif /* these may or may not be in the headers depending on the version */ #if defined(HAVE_DECL_AUTHENTICATE) && (HAVE_DECL_AUTHENTICATE == 0) int authenticate(char *, char *, int *, char **); #endif #if defined(HAVE_DECL_LOGINFAILED) && (HAVE_DECL_LOGINFAILED == 0) int loginfailed(char *, char *, char *); #endif #if defined(HAVE_DECL_LOGINRESTRICTIONS) && (HAVE_DECL_LOGINRESTRICTIONS == 0) int loginrestrictions(char *, int, char *, char **); #endif #if defined(HAVE_DECL_LOGINSUCCESS) && (HAVE_DECL_LOGINSUCCESS == 0) int loginsuccess(char *, char *, char *, char **); #endif #if defined(HAVE_DECL_PASSWDEXPIRED) && (HAVE_DECL_PASSWDEXPIRED == 0) int passwdexpired(char *, char **); #endif /* Some versions define r_type in the above headers, which causes a conflict */ #ifdef r_type # undef r_type #endif /* AIX 4.2.x doesn't have nanosleep but does have nsleep which is equivalent */ #if !defined(HAVE_NANOSLEEP) && defined(HAVE_NSLEEP) # define nanosleep(a,b) nsleep(a,b) #endif /* For struct timespec on AIX 4.2.x */ #ifdef HAVE_SYS_TIMERS_H # include #endif /* for setpcred and friends */ #ifdef HAVE_USERSEC_H # include #endif /* * According to the setauthdb man page, AIX password registries must be 15 * chars or less plus terminating NUL. */ #ifdef HAVE_SETAUTHDB # define REGISTRY_SIZE 16 #endif void aix_usrinfo(struct passwd *); #ifdef WITH_AIXAUTHENTICATE # define CUSTOM_SYS_AUTH_PASSWD 1 # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 int sys_auth_allowed_user(struct passwd *, Buffer *); # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 int sys_auth_record_login(const char *, const char *, const char *, Buffer *); # define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG char *sys_auth_get_lastlogin_msg(const char *, uid_t); # define CUSTOM_FAILED_LOGIN 1 # if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME) # define USE_AIX_KRB_NAME char *aix_krb5_get_principal_name(char *); # endif #endif void aix_setauthdb(const char *); void aix_restoreauthdb(void); void aix_remove_embedded_newlines(char *); #if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_GETADDRINFO) # ifdef getnameinfo # undef getnameinfo # endif int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) #endif /* * We use getgrset in preference to multiple getgrent calls for efficiency * plus it supports NIS and LDAP groups. */ #if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET) # define HAVE_GETGROUPLIST # define USE_GETGRSET int getgrouplist(const char *, gid_t, gid_t *, int *); #endif #endif /* _AIX */ openssh-7.2p2/openbsd-compat/port-irix.c010064400017500001750000000063011267006270000164660ustar00djmdjm/* * Copyright (c) 2000 Denis Parker. All rights reserved. * Copyright (c) 2000 Michael Stone. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #if defined(WITH_IRIX_PROJECT) || \ defined(WITH_IRIX_JOBS) || \ defined(WITH_IRIX_ARRAY) #include #include #include #ifdef WITH_IRIX_PROJECT # include #endif /* WITH_IRIX_PROJECT */ #ifdef WITH_IRIX_JOBS # include #endif #ifdef WITH_IRIX_AUDIT # include #endif /* WITH_IRIX_AUDIT */ void irix_setusercontext(struct passwd *pw) { #ifdef WITH_IRIX_PROJECT prid_t projid; #endif #ifdef WITH_IRIX_JOBS jid_t jid = 0; #elif defined(WITH_IRIX_ARRAY) int jid = 0; #endif #ifdef WITH_IRIX_JOBS jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); if (jid == -1) fatal("Failed to create job container: %.100s", strerror(errno)); #endif /* WITH_IRIX_JOBS */ #ifdef WITH_IRIX_ARRAY /* initialize array session */ if (jid == 0 && newarraysess() != 0) fatal("Failed to set up new array session: %.100s", strerror(errno)); #endif /* WITH_IRIX_ARRAY */ #ifdef WITH_IRIX_PROJECT /* initialize irix project info */ if ((projid = getdfltprojuser(pw->pw_name)) == -1) { debug("Failed to get project id, using projid 0"); projid = 0; } if (setprid(projid)) fatal("Failed to initialize project %d for %s: %.100s", (int)projid, pw->pw_name, strerror(errno)); #endif /* WITH_IRIX_PROJECT */ #ifdef WITH_IRIX_AUDIT if (sysconf(_SC_AUDIT)) { debug("Setting sat id to %d", (int) pw->pw_uid); if (satsetid(pw->pw_uid)) debug("error setting satid: %.100s", strerror(errno)); } #endif /* WITH_IRIX_AUDIT */ } #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ openssh-7.2p2/openbsd-compat/port-irix.h010064400017500001750000000033271267006270000165000ustar00djmdjm/* $Id: port-irix.h,v 1.4 2003/08/29 16:59:52 mouring Exp $ */ /* * Copyright (c) 2000 Denis Parker. All rights reserved. * Copyright (c) 2000 Michael Stone. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _PORT_IRIX_H #define _PORT_IRIX_H #if defined(WITH_IRIX_PROJECT) || \ defined(WITH_IRIX_JOBS) || \ defined(WITH_IRIX_ARRAY) void irix_setusercontext(struct passwd *pw); #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ #endif /* ! _PORT_IRIX_H */ openssh-7.2p2/openbsd-compat/port-linux.c010064400017500001750000000171121267006270000166540ustar00djmdjm/* $Id: port-linux.c,v 1.18 2013/06/01 22:07:32 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh * Copyright (c) 2006 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* * Linux-specific portability code - just SELinux support at present */ #include "includes.h" #if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) #include #include #include #include #include "log.h" #include "xmalloc.h" #include "port-linux.h" #ifdef WITH_SELINUX #include #include #include #ifndef SSH_SELINUX_UNCONFINED_TYPE # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" #endif /* Wrapper around is_selinux_enabled() to log its return value once only */ int ssh_selinux_enabled(void) { static int enabled = -1; if (enabled == -1) { enabled = (is_selinux_enabled() == 1); debug("SELinux support %s", enabled ? "enabled" : "disabled"); } return (enabled); } /* Return the default security context for the given username */ static security_context_t ssh_selinux_getctxbyname(char *pwname) { security_context_t sc = NULL; char *sename = NULL, *lvl = NULL; int r; #ifdef HAVE_GETSEUSERBYNAME if (getseuserbyname(pwname, &sename, &lvl) != 0) return NULL; #else sename = pwname; lvl = NULL; #endif #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL r = get_default_context_with_level(sename, lvl, NULL, &sc); #else r = get_default_context(sename, NULL, &sc); #endif if (r != 0) { switch (security_getenforce()) { case -1: fatal("%s: ssh_selinux_getctxbyname: " "security_getenforce() failed", __func__); case 0: error("%s: Failed to get default SELinux security " "context for %s", __func__, pwname); sc = NULL; break; default: fatal("%s: Failed to get default SELinux security " "context for %s (in enforcing mode)", __func__, pwname); } } #ifdef HAVE_GETSEUSERBYNAME free(sename); free(lvl); #endif return sc; } /* Set the execution context to the default for the specified user */ void ssh_selinux_setup_exec_context(char *pwname) { security_context_t user_ctx = NULL; if (!ssh_selinux_enabled()) return; debug3("%s: setting execution context", __func__); user_ctx = ssh_selinux_getctxbyname(pwname); if (setexeccon(user_ctx) != 0) { switch (security_getenforce()) { case -1: fatal("%s: security_getenforce() failed", __func__); case 0: error("%s: Failed to set SELinux execution " "context for %s", __func__, pwname); break; default: fatal("%s: Failed to set SELinux execution context " "for %s (in enforcing mode)", __func__, pwname); } } if (user_ctx != NULL) freecon(user_ctx); debug3("%s: done", __func__); } /* Set the TTY context for the specified user */ void ssh_selinux_setup_pty(char *pwname, const char *tty) { security_context_t new_tty_ctx = NULL; security_context_t user_ctx = NULL; security_context_t old_tty_ctx = NULL; if (!ssh_selinux_enabled()) return; debug3("%s: setting TTY context on %s", __func__, tty); user_ctx = ssh_selinux_getctxbyname(pwname); /* XXX: should these calls fatal() upon failure in enforcing mode? */ if (getfilecon(tty, &old_tty_ctx) == -1) { error("%s: getfilecon: %s", __func__, strerror(errno)); goto out; } if (security_compute_relabel(user_ctx, old_tty_ctx, SECCLASS_CHR_FILE, &new_tty_ctx) != 0) { error("%s: security_compute_relabel: %s", __func__, strerror(errno)); goto out; } if (setfilecon(tty, new_tty_ctx) != 0) error("%s: setfilecon: %s", __func__, strerror(errno)); out: if (new_tty_ctx != NULL) freecon(new_tty_ctx); if (old_tty_ctx != NULL) freecon(old_tty_ctx); if (user_ctx != NULL) freecon(user_ctx); debug3("%s: done", __func__); } void ssh_selinux_change_context(const char *newname) { int len, newlen; char *oldctx, *newctx, *cx; void (*switchlog) (const char *fmt,...) = logit; if (!ssh_selinux_enabled()) return; if (getcon((security_context_t *)&oldctx) < 0) { logit("%s: getcon failed with %s", __func__, strerror(errno)); return; } if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) == NULL) { logit ("%s: unparseable context %s", __func__, oldctx); return; } /* * Check whether we are attempting to switch away from an unconfined * security context. */ if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE, sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0) switchlog = debug3; newlen = strlen(oldctx) + strlen(newname) + 1; newctx = xmalloc(newlen); len = cx - oldctx + 1; memcpy(newctx, oldctx, len); strlcpy(newctx + len, newname, newlen - len); if ((cx = index(cx + 1, ':'))) strlcat(newctx, cx, newlen); debug3("%s: setting context from '%s' to '%s'", __func__, oldctx, newctx); if (setcon(newctx) < 0) switchlog("%s: setcon %s from %s failed with %s", __func__, newctx, oldctx, strerror(errno)); free(oldctx); free(newctx); } void ssh_selinux_setfscreatecon(const char *path) { security_context_t context; if (!ssh_selinux_enabled()) return; if (path == NULL) { setfscreatecon(NULL); return; } if (matchpathcon(path, 0700, &context) == 0) setfscreatecon(context); } #endif /* WITH_SELINUX */ #ifdef LINUX_OOM_ADJUST /* * The magic "don't kill me" values, old and new, as documented in eg: * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt */ static int oom_adj_save = INT_MIN; static char *oom_adj_path = NULL; struct { char *path; int value; } oom_adjust[] = { {"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */ {"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */ {NULL, 0}, }; /* * Tell the kernel's out-of-memory killer to avoid sshd. * Returns the previous oom_adj value or zero. */ void oom_adjust_setup(void) { int i, value; FILE *fp; debug3("%s", __func__); for (i = 0; oom_adjust[i].path != NULL; i++) { oom_adj_path = oom_adjust[i].path; value = oom_adjust[i].value; if ((fp = fopen(oom_adj_path, "r+")) != NULL) { if (fscanf(fp, "%d", &oom_adj_save) != 1) verbose("error reading %s: %s", oom_adj_path, strerror(errno)); else { rewind(fp); if (fprintf(fp, "%d\n", value) <= 0) verbose("error writing %s: %s", oom_adj_path, strerror(errno)); else debug("Set %s from %d to %d", oom_adj_path, oom_adj_save, value); } fclose(fp); return; } } oom_adj_path = NULL; } /* Restore the saved OOM adjustment */ void oom_adjust_restore(void) { FILE *fp; debug3("%s", __func__); if (oom_adj_save == INT_MIN || oom_adj_path == NULL || (fp = fopen(oom_adj_path, "w")) == NULL) return; if (fprintf(fp, "%d\n", oom_adj_save) <= 0) verbose("error writing %s: %s", oom_adj_path, strerror(errno)); else debug("Set %s to %d", oom_adj_path, oom_adj_save); fclose(fp); return; } #endif /* LINUX_OOM_ADJUST */ #endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ openssh-7.2p2/openbsd-compat/port-linux.h010064400017500001750000000023621267006270000166620ustar00djmdjm/* $Id: port-linux.h,v 1.5 2011/01/25 01:16:18 djm Exp $ */ /* * Copyright (c) 2006 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _PORT_LINUX_H #define _PORT_LINUX_H #ifdef WITH_SELINUX int ssh_selinux_enabled(void); void ssh_selinux_setup_pty(char *, const char *); void ssh_selinux_setup_exec_context(char *); void ssh_selinux_change_context(const char *); void ssh_selinux_setfscreatecon(const char *); #endif #ifdef LINUX_OOM_ADJUST void oom_adjust_restore(void); void oom_adjust_setup(void); #endif #endif /* ! _PORT_LINUX_H */ openssh-7.2p2/openbsd-compat/port-solaris.c010064400017500001750000000231751267006270000171770ustar00djmdjm/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */ /* * Copyright (c) 2006 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 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 "config.h" #include "includes.h" #ifdef USE_SOLARIS_PROCESS_CONTRACTS #include #include #include #include #ifdef HAVE_FCNTL_H # include #endif #include #include #include #include #include #include #include "log.h" #define CT_TEMPLATE CTFS_ROOT "/process/template" #define CT_LATEST CTFS_ROOT "/process/latest" static int tmpl_fd = -1; /* Lookup the latest process contract */ static ctid_t get_active_process_contract_id(void) { int stat_fd; ctid_t ctid = -1; ct_stathdl_t stathdl; if ((stat_fd = open64(CT_LATEST, O_RDONLY)) == -1) { error("%s: Error opening 'latest' process " "contract: %s", __func__, strerror(errno)); return -1; } if (ct_status_read(stat_fd, CTD_COMMON, &stathdl) != 0) { error("%s: Error reading process contract " "status: %s", __func__, strerror(errno)); goto out; } if ((ctid = ct_status_get_id(stathdl)) < 0) { error("%s: Error getting process contract id: %s", __func__, strerror(errno)); goto out; } ct_status_free(stathdl); out: close(stat_fd); return ctid; } void solaris_contract_pre_fork(void) { if ((tmpl_fd = open64(CT_TEMPLATE, O_RDWR)) == -1) { error("%s: open %s: %s", __func__, CT_TEMPLATE, strerror(errno)); return; } debug2("%s: setting up process contract template on fd %d", __func__, tmpl_fd); /* First we set the template parameters and event sets. */ if (ct_pr_tmpl_set_param(tmpl_fd, CT_PR_PGRPONLY) != 0) { error("%s: Error setting process contract parameter set " "(pgrponly): %s", __func__, strerror(errno)); goto fail; } if (ct_pr_tmpl_set_fatal(tmpl_fd, CT_PR_EV_HWERR) != 0) { error("%s: Error setting process contract template " "fatal events: %s", __func__, strerror(errno)); goto fail; } if (ct_tmpl_set_critical(tmpl_fd, 0) != 0) { error("%s: Error setting process contract template " "critical events: %s", __func__, strerror(errno)); goto fail; } if (ct_tmpl_set_informative(tmpl_fd, CT_PR_EV_HWERR) != 0) { error("%s: Error setting process contract template " "informative events: %s", __func__, strerror(errno)); goto fail; } /* Now make this the active template for this process. */ if (ct_tmpl_activate(tmpl_fd) != 0) { error("%s: Error activating process contract " "template: %s", __func__, strerror(errno)); goto fail; } return; fail: if (tmpl_fd != -1) { close(tmpl_fd); tmpl_fd = -1; } } void solaris_contract_post_fork_child() { debug2("%s: clearing process contract template on fd %d", __func__, tmpl_fd); /* Clear the active template. */ if (ct_tmpl_clear(tmpl_fd) != 0) error("%s: Error clearing active process contract " "template: %s", __func__, strerror(errno)); close(tmpl_fd); tmpl_fd = -1; } void solaris_contract_post_fork_parent(pid_t pid) { ctid_t ctid; char ctl_path[256]; int r, ctl_fd = -1, stat_fd = -1; debug2("%s: clearing template (fd %d)", __func__, tmpl_fd); if (tmpl_fd == -1) return; /* First clear the active template. */ if ((r = ct_tmpl_clear(tmpl_fd)) != 0) error("%s: Error clearing active process contract " "template: %s", __func__, strerror(errno)); close(tmpl_fd); tmpl_fd = -1; /* * If either the fork didn't succeed (pid < 0), or clearing * th active contract failed (r != 0), then we have nothing * more do. */ if (r != 0 || pid <= 0) return; /* Now lookup and abandon the contract we've created. */ ctid = get_active_process_contract_id(); debug2("%s: abandoning contract id %ld", __func__, ctid); snprintf(ctl_path, sizeof(ctl_path), CTFS_ROOT "/process/%ld/ctl", ctid); if ((ctl_fd = open64(ctl_path, O_WRONLY)) < 0) { error("%s: Error opening process contract " "ctl file: %s", __func__, strerror(errno)); goto fail; } if (ct_ctl_abandon(ctl_fd) < 0) { error("%s: Error abandoning process contract: %s", __func__, strerror(errno)); goto fail; } close(ctl_fd); return; fail: if (tmpl_fd != -1) { close(tmpl_fd); tmpl_fd = -1; } if (stat_fd != -1) close(stat_fd); if (ctl_fd != -1) close(ctl_fd); } #endif #ifdef USE_SOLARIS_PROJECTS #include #include /* * Get/set solaris default project. * If we fail, just run along gracefully. */ void solaris_set_default_project(struct passwd *pw) { struct project *defaultproject; struct project tempproject; char buf[1024]; /* get default project, if we fail just return gracefully */ if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf, sizeof(buf))) > 0) { /* set default project */ if (setproject(defaultproject->pj_name, pw->pw_name, TASK_NORMAL) != 0) debug("setproject(%s): %s", defaultproject->pj_name, strerror(errno)); } else { /* debug on getdefaultproj() error */ debug("getdefaultproj(%s): %s", pw->pw_name, strerror(errno)); } } #endif /* USE_SOLARIS_PROJECTS */ #ifdef USE_SOLARIS_PRIVS # ifdef HAVE_PRIV_H # include # endif priv_set_t * solaris_basic_privset(void) { priv_set_t *pset; #ifdef HAVE_PRIV_BASICSET if ((pset = priv_allocset()) == NULL) { error("priv_allocset: %s", strerror(errno)); return NULL; } priv_basicset(pset); #else if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) { error("priv_str_to_set: %s", strerror(errno)); return NULL; } #endif return pset; } void solaris_drop_privs_pinfo_net_fork_exec(void) { priv_set_t *pset = NULL, *npset = NULL; /* * Note: this variant avoids dropping DAC filesystem rights, in case * the process calling it is running as root and should have the * ability to read/write/chown any file on the system. * * We start with the basic set, then *add* the DAC rights to it while * taking away other parts of BASIC we don't need. Then we intersect * this with our existing PERMITTED set. In this way we keep any * DAC rights we had before, while otherwise reducing ourselves to * the minimum set of privileges we need to proceed. * * This also means we drop any other parts of "root" that we don't * need (e.g. the ability to kill any process, create new device nodes * etc etc). */ if ((pset = priv_allocset()) == NULL) fatal("priv_allocset: %s", strerror(errno)); if ((npset = solaris_basic_privset()) == NULL) fatal("solaris_basic_privset: %s", strerror(errno)); if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 || priv_addset(npset, PRIV_FILE_DAC_READ) != 0 || priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 || priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 || priv_addset(npset, PRIV_FILE_OWNER) != 0) fatal("priv_addset: %s", strerror(errno)); if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 || #ifdef PRIV_NET_ACCESS priv_delset(npset, PRIV_NET_ACCESS) != 0 || #endif priv_delset(npset, PRIV_PROC_EXEC) != 0 || priv_delset(npset, PRIV_PROC_FORK) != 0 || priv_delset(npset, PRIV_PROC_INFO) != 0 || priv_delset(npset, PRIV_PROC_SESSION) != 0) fatal("priv_delset: %s", strerror(errno)); if (getppriv(PRIV_PERMITTED, pset) != 0) fatal("getppriv: %s", strerror(errno)); priv_intersect(pset, npset); if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 || setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 || setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0) fatal("setppriv: %s", strerror(errno)); priv_freeset(pset); priv_freeset(npset); } void solaris_drop_privs_root_pinfo_net(void) { priv_set_t *pset = NULL; /* Start with "basic" and drop everything we don't need. */ if ((pset = solaris_basic_privset()) == NULL) fatal("solaris_basic_privset: %s", strerror(errno)); if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || #ifdef PRIV_NET_ACCESS priv_delset(pset, PRIV_NET_ACCESS) != 0 || #endif priv_delset(pset, PRIV_PROC_INFO) != 0 || priv_delset(pset, PRIV_PROC_SESSION) != 0) fatal("priv_delset: %s", strerror(errno)); if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) fatal("setppriv: %s", strerror(errno)); priv_freeset(pset); } void solaris_drop_privs_root_pinfo_net_exec(void) { priv_set_t *pset = NULL; /* Start with "basic" and drop everything we don't need. */ if ((pset = solaris_basic_privset()) == NULL) fatal("solaris_basic_privset: %s", strerror(errno)); if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || #ifdef PRIV_NET_ACCESS priv_delset(pset, PRIV_NET_ACCESS) != 0 || #endif priv_delset(pset, PRIV_PROC_EXEC) != 0 || priv_delset(pset, PRIV_PROC_INFO) != 0 || priv_delset(pset, PRIV_PROC_SESSION) != 0) fatal("priv_delset: %s", strerror(errno)); if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) fatal("setppriv: %s", strerror(errno)); priv_freeset(pset); } #endif openssh-7.2p2/openbsd-compat/port-solaris.h010064400017500001750000000025031267006270000171740ustar00djmdjm/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */ /* * Copyright (c) 2006 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 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 _PORT_SOLARIS_H #include #include void solaris_contract_pre_fork(void); void solaris_contract_post_fork_child(void); void solaris_contract_post_fork_parent(pid_t pid); void solaris_set_default_project(struct passwd *); # ifdef USE_SOLARIS_PRIVS priv_set_t *solaris_basic_privset(void); void solaris_drop_privs_pinfo_net_fork_exec(void); void solaris_drop_privs_root_pinfo_net(void); void solaris_drop_privs_root_pinfo_net_exec(void); # endif /* USE_SOLARIS_PRIVS */ #endif openssh-7.2p2/openbsd-compat/port-tun.c010064400017500001750000000143461267006270000163310ustar00djmdjm/* * Copyright (c) 2005 Reyk Floeter * * 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 #include #include #include #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "log.h" #include "misc.h" #include "sshbuf.h" #include "channels.h" #include "ssherr.h" /* * This is the portable version of the SSH tunnel forwarding, it * uses some preprocessor definitions for various platform-specific * settings. * * SSH_TUN_LINUX Use the (newer) Linux tun/tap device * SSH_TUN_FREEBSD Use the FreeBSD tun/tap device * SSH_TUN_COMPAT_AF Translate the OpenBSD address family * SSH_TUN_PREPEND_AF Prepend/remove the address family */ /* * System-specific tunnel open function */ #if defined(SSH_TUN_LINUX) #include #include int sys_tun_open(int tun, int mode) { struct ifreq ifr; int fd = -1; const char *name = NULL; if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { debug("%s: failed to open tunnel control interface: %s", __func__, strerror(errno)); return (-1); } bzero(&ifr, sizeof(ifr)); if (mode == SSH_TUNMODE_ETHERNET) { ifr.ifr_flags = IFF_TAP; name = "tap%d"; } else { ifr.ifr_flags = IFF_TUN; name = "tun%d"; } ifr.ifr_flags |= IFF_NO_PI; if (tun != SSH_TUNID_ANY) { if (tun > SSH_TUNID_MAX) { debug("%s: invalid tunnel id %x: %s", __func__, tun, strerror(errno)); goto failed; } snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), name, tun); } if (ioctl(fd, TUNSETIFF, &ifr) == -1) { debug("%s: failed to configure tunnel (mode %d): %s", __func__, mode, strerror(errno)); goto failed; } if (tun == SSH_TUNID_ANY) debug("%s: tunnel mode %d fd %d", __func__, mode, fd); else debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); return (fd); failed: close(fd); return (-1); } #endif /* SSH_TUN_LINUX */ #ifdef SSH_TUN_FREEBSD #include #include #ifdef HAVE_NET_IF_TUN_H #include #endif int sys_tun_open(int tun, int mode) { struct ifreq ifr; char name[100]; int fd = -1, sock, flag; const char *tunbase = "tun"; if (mode == SSH_TUNMODE_ETHERNET) { #ifdef SSH_TUN_NO_L2 debug("%s: no layer 2 tunnelling support", __func__); return (-1); #else tunbase = "tap"; #endif } /* Open the tunnel device */ if (tun <= SSH_TUNID_MAX) { snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); fd = open(name, O_RDWR); } else if (tun == SSH_TUNID_ANY) { for (tun = 100; tun >= 0; tun--) { snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); if ((fd = open(name, O_RDWR)) >= 0) break; } } else { debug("%s: invalid tunnel %u\n", __func__, tun); return (-1); } if (fd < 0) { debug("%s: %s open failed: %s", __func__, name, strerror(errno)); return (-1); } /* Turn on tunnel headers */ flag = 1; #if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF) if (mode != SSH_TUNMODE_ETHERNET && ioctl(fd, TUNSIFHEAD, &flag) == -1) { debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, strerror(errno)); close(fd); } #endif debug("%s: %s mode %d fd %d", __func__, name, mode, fd); /* Set the tunnel device operation mode */ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) goto failed; if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) goto failed; if ((ifr.ifr_flags & IFF_UP) == 0) { ifr.ifr_flags |= IFF_UP; if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) goto failed; } close(sock); return (fd); failed: if (fd >= 0) close(fd); if (sock >= 0) close(sock); debug("%s: failed to set %s mode %d: %s", __func__, name, mode, strerror(errno)); return (-1); } #endif /* SSH_TUN_FREEBSD */ /* * System-specific channel filters */ #if defined(SSH_TUN_FILTER) #define OPENBSD_AF_INET 2 #define OPENBSD_AF_INET6 24 int sys_tun_infilter(struct Channel *c, char *buf, int len) { #if defined(SSH_TUN_PREPEND_AF) char rbuf[CHAN_RBUF]; struct ip *iph; #endif u_int32_t *af; char *ptr = buf; int r; #if defined(SSH_TUN_PREPEND_AF) if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) return (-1); ptr = (char *)&rbuf[0]; bcopy(buf, ptr + sizeof(u_int32_t), len); len += sizeof(u_int32_t); af = (u_int32_t *)ptr; iph = (struct ip *)(ptr + sizeof(u_int32_t)); switch (iph->ip_v) { case 6: *af = AF_INET6; break; case 4: default: *af = AF_INET; break; } #endif #if defined(SSH_TUN_COMPAT_AF) if (len < (int)sizeof(u_int32_t)) return (-1); af = (u_int32_t *)ptr; if (*af == htonl(AF_INET6)) *af = htonl(OPENBSD_AF_INET6); else *af = htonl(OPENBSD_AF_INET); #endif if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); return (0); } u_char * sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) { u_char *buf; u_int32_t *af; int r; size_t xxx_dlen; /* XXX new API is incompatible with this signature. */ if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (dlen != NULL) *dlen = xxx_dlen; if (*dlen < sizeof(*af)) return (NULL); buf = *data; #if defined(SSH_TUN_PREPEND_AF) *dlen -= sizeof(u_int32_t); buf = *data + sizeof(u_int32_t); #elif defined(SSH_TUN_COMPAT_AF) af = ntohl(*(u_int32_t *)buf); if (*af == OPENBSD_AF_INET6) *af = htonl(AF_INET6); else *af = htonl(AF_INET); #endif return (buf); } #endif /* SSH_TUN_FILTER */ openssh-7.2p2/openbsd-compat/port-tun.h010064400017500001750000000022471267006270000163330ustar00djmdjm/* * Copyright (c) 2005 Reyk Floeter * * 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 _PORT_TUN_H #define _PORT_TUN_H struct Channel; #if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) # define CUSTOM_SYS_TUN_OPEN int sys_tun_open(int, int); #endif #if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) # define SSH_TUN_FILTER int sys_tun_infilter(struct Channel *, char *, int); u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); #endif #endif openssh-7.2p2/openbsd-compat/port-uw.c010064400017500001750000000101551267006270000161500ustar00djmdjm/* * Copyright (c) 2005 The SCO Group. All rights reserved. * Copyright (c) 2005 Tim Rice. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #if defined(HAVE_LIBIAF) && !defined(HAVE_SECUREWARE) #include #ifdef HAVE_CRYPT_H # include #endif #include #include #include #include #include #include "xmalloc.h" #include "packet.h" #include "buffer.h" #include "key.h" #include "auth-options.h" #include "log.h" #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ #include "servconf.h" #include "hostfile.h" #include "auth.h" #include "ssh.h" int nischeck(char *); int sys_auth_passwd(Authctxt *authctxt, const char *password) { struct passwd *pw = authctxt->pw; char *salt; int result; /* 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. */ salt = (pw_password[0] && pw_password[1]) ? pw_password : "xx"; /* * Authentication is accepted if the encrypted passwords * are identical. */ #ifdef UNIXWARE_LONG_PASSWORDS if (!nischeck(pw->pw_name)) { result = ((strcmp(bigcrypt(password, salt), pw_password) == 0) || (strcmp(osr5bigcrypt(password, salt), pw_password) == 0)); } else #endif /* UNIXWARE_LONG_PASSWORDS */ result = (strcmp(xcrypt(password, salt), pw_password) == 0); #ifdef USE_LIBIAF if (authctxt->valid) free(pw_password); #endif return(result); } #ifdef UNIXWARE_LONG_PASSWORDS int nischeck(char *namep) { char password_file[] = "/etc/passwd"; FILE *fd; struct passwd *ent = NULL; if ((fd = fopen (password_file, "r")) == NULL) { /* * If the passwd file has dissapeared we are in a bad state. * However, returning 0 will send us back through the * authentication scheme that has checked the ia database for * passwords earlier. */ return(0); } /* * fgetpwent() only reads from password file, so we know for certain * that the user is local. */ while (ent = fgetpwent(fd)) { if (strcmp (ent->pw_name, namep) == 0) { /* Local user */ fclose (fd); return(0); } } fclose (fd); return (1); } #endif /* UNIXWARE_LONG_PASSWORDS */ /* NOTE: ia_get_logpwd() allocates memory for arg 2 functions that call shadow_pw() will need to free */ #ifdef USE_LIBIAF char * get_iaf_password(struct passwd *pw) { char *pw_password = NULL; uinfo_t uinfo; if (!ia_openinfo(pw->pw_name,&uinfo)) { ia_get_logpwd(uinfo, &pw_password); if (pw_password == NULL) fatal("ia_get_logpwd: Unable to get the shadow passwd"); ia_closeinfo(uinfo); return pw_password; } else fatal("ia_openinfo: Unable to open the shadow passwd file"); } #endif /* USE_LIBIAF */ #endif /* HAVE_LIBIAF and not HAVE_SECUREWARE */ openssh-7.2p2/openbsd-compat/port-uw.h010064400017500001750000000025751267006270000161640ustar00djmdjm/* * Copyright (c) 2005 Tim Rice. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #ifdef USE_LIBIAF char * get_iaf_password(struct passwd *pw); #endif openssh-7.2p2/openbsd-compat/pwcache.c010064400017500001750000000063421267006270000161500ustar00djmdjm/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */ /* * Copyright (c) 1989, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */ #include "includes.h" #include #include #include #include #include #include #define NCACHE 64 /* power of 2 */ #define MASK (NCACHE - 1) /* bits to store with */ #ifndef HAVE_USER_FROM_UID char * user_from_uid(uid_t uid, int nouser) { static struct ncache { uid_t uid; char *name; } c_uid[NCACHE]; static int pwopen; static char nbuf[15]; /* 32 bits == 10 digits */ struct passwd *pw; struct ncache *cp; cp = c_uid + (uid & MASK); if (cp->uid != uid || cp->name == NULL) { if (pwopen == 0) { #ifdef HAVE_SETPASSENT setpassent(1); #endif pwopen = 1; } if ((pw = getpwuid(uid)) == NULL) { if (nouser) return (NULL); (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); } cp->uid = uid; if (cp->name != NULL) free(cp->name); cp->name = strdup(pw ? pw->pw_name : nbuf); } return (cp->name); } #endif #ifndef HAVE_GROUP_FROM_GID char * group_from_gid(gid_t gid, int nogroup) { static struct ncache { gid_t gid; char *name; } c_gid[NCACHE]; static int gropen; static char nbuf[15]; /* 32 bits == 10 digits */ struct group *gr; struct ncache *cp; cp = c_gid + (gid & MASK); if (cp->gid != gid || cp->name == NULL) { if (gropen == 0) { #ifdef HAVE_SETGROUPENT setgroupent(1); #endif gropen = 1; } if ((gr = getgrgid(gid)) == NULL) { if (nogroup) return (NULL); (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); } cp->gid = gid; if (cp->name != NULL) free(cp->name); cp->name = strdup(gr ? gr->gr_name : nbuf); } return (cp->name); } #endif openssh-7.2p2/openbsd-compat/readpassphrase.c010064400017500001750000000131361267006270000175420ustar00djmdjm/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ /* * Copyright (c) 2000-2002, 2007 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ /* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ #include "includes.h" #ifndef HAVE_READPASSPHRASE #include #include #include #include #include #include #include #include #ifdef TCSASOFT # define _T_FLUSH (TCSAFLUSH|TCSASOFT) #else # define _T_FLUSH (TCSAFLUSH) #endif /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ #if !defined(_POSIX_VDISABLE) && defined(VDISABLE) # define _POSIX_VDISABLE VDISABLE #endif #ifndef _NSIG # ifdef NSIG # define _NSIG NSIG # else # define _NSIG 128 # endif #endif static volatile sig_atomic_t signo[_NSIG]; static void handler(int); char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { ssize_t nr; int input, output, save_errno, i, need_restart; char ch, *p, *end; struct termios term, oterm; struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; struct sigaction savetstp, savettin, savettou, savepipe; /* I suppose we could alloc on demand in this case (XXX). */ if (bufsiz == 0) { errno = EINVAL; return(NULL); } restart: for (i = 0; i < _NSIG; i++) signo[i] = 0; nr = -1; save_errno = 0; need_restart = 0; /* * Read and write to /dev/tty if available. If not, read from * stdin and write to stderr unless a tty is required. */ if ((flags & RPP_STDIN) || (input = output = open(_PATH_TTY, O_RDWR)) == -1) { if (flags & RPP_REQUIRE_TTY) { errno = ENOTTY; return(NULL); } input = STDIN_FILENO; output = STDERR_FILENO; } /* * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. Don't worry about * things like SIGXCPU and SIGVTALRM for now. */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* don't restart system calls */ sa.sa_handler = handler; (void)sigaction(SIGALRM, &sa, &savealrm); (void)sigaction(SIGHUP, &sa, &savehup); (void)sigaction(SIGINT, &sa, &saveint); (void)sigaction(SIGPIPE, &sa, &savepipe); (void)sigaction(SIGQUIT, &sa, &savequit); (void)sigaction(SIGTERM, &sa, &saveterm); (void)sigaction(SIGTSTP, &sa, &savetstp); (void)sigaction(SIGTTIN, &sa, &savettin); (void)sigaction(SIGTTOU, &sa, &savettou); /* Turn off echo if possible. */ if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { memcpy(&term, &oterm, sizeof(term)); if (!(flags & RPP_ECHO_ON)) term.c_lflag &= ~(ECHO | ECHONL); #ifdef VSTATUS if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) term.c_cc[VSTATUS] = _POSIX_VDISABLE; #endif (void)tcsetattr(input, _T_FLUSH, &term); } else { memset(&term, 0, sizeof(term)); term.c_lflag |= ECHO; memset(&oterm, 0, sizeof(oterm)); oterm.c_lflag |= ECHO; } /* No I/O if we are already backgrounded. */ if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { if (!(flags & RPP_STDIN)) (void)write(output, prompt, strlen(prompt)); end = buf + bufsiz - 1; p = buf; while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { if (p < end) { if ((flags & RPP_SEVENBIT)) ch &= 0x7f; if (isalpha(ch)) { if ((flags & RPP_FORCELOWER)) ch = (char)tolower(ch); if ((flags & RPP_FORCEUPPER)) ch = (char)toupper(ch); } *p++ = ch; } } *p = '\0'; save_errno = errno; if (!(term.c_lflag & ECHO)) (void)write(output, "\n", 1); } /* Restore old terminal settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) { while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && errno == EINTR) continue; } (void)sigaction(SIGALRM, &savealrm, NULL); (void)sigaction(SIGHUP, &savehup, NULL); (void)sigaction(SIGINT, &saveint, NULL); (void)sigaction(SIGQUIT, &savequit, NULL); (void)sigaction(SIGPIPE, &savepipe, NULL); (void)sigaction(SIGTERM, &saveterm, NULL); (void)sigaction(SIGTSTP, &savetstp, NULL); (void)sigaction(SIGTTIN, &savettin, NULL); (void)sigaction(SIGTTOU, &savettou, NULL); if (input != STDIN_FILENO) (void)close(input); /* * If we were interrupted by a signal, resend it to ourselves * now that we have restored the signal handlers. */ for (i = 0; i < _NSIG; i++) { if (signo[i]) { kill(getpid(), i); switch (i) { case SIGTSTP: case SIGTTIN: case SIGTTOU: need_restart = 1; } } } if (need_restart) goto restart; if (save_errno) errno = save_errno; return(nr == -1 ? NULL : buf); } #if 0 char * getpass(const char *prompt) { static char buf[_PASSWORD_LEN + 1]; return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); } #endif static void handler(int s) { signo[s] = 1; } #endif /* HAVE_READPASSPHRASE */ openssh-7.2p2/openbsd-compat/readpassphrase.h010064400017500001750000000034031267006270000175430ustar00djmdjm/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ /* * Copyright (c) 2000, 2002 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ /* OPENBSD ORIGINAL: include/readpassphrase.h */ #ifndef _READPASSPHRASE_H_ #define _READPASSPHRASE_H_ #include "includes.h" #ifndef HAVE_READPASSPHRASE #define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ #define RPP_ECHO_ON 0x01 /* Leave echo on. */ #define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ #define RPP_FORCELOWER 0x04 /* Force input to lower case. */ #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ #define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ char * readpassphrase(const char *, char *, size_t, int); #endif /* HAVE_READPASSPHRASE */ #endif /* !_READPASSPHRASE_H_ */ openssh-7.2p2/openbsd-compat/reallocarray.c010064400017500001750000000027641267006270000172220ustar00djmdjm/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ /* * Copyright (c) 2008 Otto Moerbeek * * 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/reallocarray.c */ #include "includes.h" #ifndef HAVE_REALLOCARRAY #include #include #ifdef HAVE_STDINT_H #include #endif #include /* * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW */ #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) void * reallocarray(void *optr, size_t nmemb, size_t size) { if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) { errno = ENOMEM; return NULL; } return realloc(optr, size * nmemb); } #endif /* HAVE_REALLOCARRAY */ openssh-7.2p2/openbsd-compat/realpath.c010064400017500001750000000141171267006270000163350ustar00djmdjm/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */ /* * Copyright (c) 2003 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. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/realpath.c */ #include "includes.h" #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) #include #include #include #include #include #include #include #include #include #ifndef SYMLOOP_MAX # define SYMLOOP_MAX 32 #endif /* A slightly modified copy of this file exists in libexec/ld.so */ /* * char *realpath(const char *path, char resolved[PATH_MAX]); * * Find the real name of path, by removing all ".", ".." and symlink * components. Returns (resolved) on success, or (NULL) on failure, * in which case the path which caused trouble is left in (resolved). */ char * realpath(const char *path, char *resolved) { struct stat sb; char *p, *q, *s; size_t left_len, resolved_len; unsigned symlinks; int serrno, slen, mem_allocated; char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; if (path[0] == '\0') { errno = ENOENT; return (NULL); } serrno = errno; if (resolved == NULL) { resolved = malloc(PATH_MAX); if (resolved == NULL) return (NULL); mem_allocated = 1; } else mem_allocated = 0; symlinks = 0; if (path[0] == '/') { resolved[0] = '/'; resolved[1] = '\0'; if (path[1] == '\0') return (resolved); resolved_len = 1; left_len = strlcpy(left, path + 1, sizeof(left)); } else { if (getcwd(resolved, PATH_MAX) == NULL) { if (mem_allocated) free(resolved); else strlcpy(resolved, ".", PATH_MAX); return (NULL); } resolved_len = strlen(resolved); left_len = strlcpy(left, path, sizeof(left)); } if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; goto err; } /* * Iterate over path components in `left'. */ while (left_len != 0) { /* * Extract the next path component and adjust `left' * and its length. */ p = strchr(left, '/'); s = p ? p : left + left_len; if (s - left >= (ptrdiff_t)sizeof(next_token)) { errno = ENAMETOOLONG; goto err; } memcpy(next_token, left, s - left); next_token[s - left] = '\0'; left_len -= s - left; if (p != NULL) memmove(left, s + 1, left_len + 1); if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; goto err; } resolved[resolved_len++] = '/'; resolved[resolved_len] = '\0'; } if (next_token[0] == '\0') continue; else if (strcmp(next_token, ".") == 0) continue; else if (strcmp(next_token, "..") == 0) { /* * Strip the last path component except when we have * single "/" */ if (resolved_len > 1) { resolved[resolved_len - 1] = '\0'; q = strrchr(resolved, '/') + 1; *q = '\0'; resolved_len = q - resolved; } continue; } /* * Append the next path component and lstat() it. If * lstat() fails we still can return successfully if * there are no more path components left. */ resolved_len = strlcat(resolved, next_token, PATH_MAX); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; goto err; } if (lstat(resolved, &sb) != 0) { if (errno == ENOENT && p == NULL) { errno = serrno; return (resolved); } goto err; } if (S_ISLNK(sb.st_mode)) { if (symlinks++ > SYMLOOP_MAX) { errno = ELOOP; goto err; } slen = readlink(resolved, symlink, sizeof(symlink) - 1); if (slen < 0) goto err; symlink[slen] = '\0'; if (symlink[0] == '/') { resolved[1] = 0; resolved_len = 1; } else if (resolved_len > 1) { /* Strip the last path component. */ resolved[resolved_len - 1] = '\0'; q = strrchr(resolved, '/') + 1; *q = '\0'; resolved_len = q - resolved; } /* * If there are any path components left, then * append them to symlink. The result is placed * in `left'. */ if (p != NULL) { if (symlink[slen - 1] != '/') { if (slen + 1 >= (ptrdiff_t)sizeof(symlink)) { errno = ENAMETOOLONG; goto err; } symlink[slen] = '/'; symlink[slen + 1] = 0; } left_len = strlcat(symlink, left, sizeof(symlink)); if (left_len >= sizeof(symlink)) { errno = ENAMETOOLONG; goto err; } } left_len = strlcpy(left, symlink, sizeof(left)); } } /* * Remove trailing slash except when the resolved pathname * is a single "/". */ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') resolved[resolved_len - 1] = '\0'; return (resolved); err: if (mem_allocated) free(resolved); return (NULL); } #endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ openssh-7.2p2/openbsd-compat/regress004075500017500001750000000000001267006270000157635ustar00djmdjmopenssh-7.2p2/openbsd-compat/regress/.cvsignore010064400017500001750000000001131267006270000200320ustar00djmdjmMakefile snprintftest strduptest strtonumtest closefromtest opensslvertest openssh-7.2p2/openbsd-compat/regress/Makefile.in010064400017500001750000000015661267006270000201140ustar00djmdjm# $Id: Makefile.in,v 1.5 2014/06/17 13:06:08 dtucker Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ srcdir=@srcdir@ top_srcdir=@top_srcdir@ VPATH=@srcdir@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ EXEEXT=@EXEEXT@ LIBCOMPAT=../libopenbsd-compat.a LIBS=@LIBS@ LDFLAGS=@LDFLAGS@ $(LIBCOMPAT) TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \ strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) all: t-exec ${OTHERTESTS} %$(EXEEXT): %.c $(LIBCOMPAT) $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBCOMPAT) $(LIBS) t-exec: $(TESTPROGS) @echo running compat regress tests @for TEST in ""$?; do \ echo "run test $${TEST}" ... 1>&2; \ ./$${TEST}$(EXEEXT) || exit $$? ; \ done @echo finished compat regress tests clean: rm -f *.o *.a core $(TESTPROGS) valid.out distclean: clean rm -f Makefile *~ openssh-7.2p2/openbsd-compat/regress/closefromtest.c010064400017500001750000000032131267006270000210730ustar00djmdjm/* * Copyright (c) 2006 Darren Tucker * * 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 #include #include #include #include #include #define NUM_OPENS 10 int closefrom(int); void fail(char *msg) { fprintf(stderr, "closefrom: %s\n", msg); exit(1); } int main(void) { int i, max, fds[NUM_OPENS]; char buf[512]; for (i = 0; i < NUM_OPENS; i++) if ((fds[i] = open("/dev/null", O_RDONLY)) == -1) exit(0); /* can't test */ max = i - 1; /* should close last fd only */ closefrom(fds[max]); if (close(fds[max]) != -1) fail("failed to close highest fd"); /* make sure we can still use remaining descriptors */ for (i = 0; i < max; i++) if (read(fds[i], buf, sizeof(buf)) == -1) fail("closed descriptors it should not have"); /* should close all fds */ closefrom(fds[0]); for (i = 0; i < NUM_OPENS; i++) if (close(fds[i]) != -1) fail("failed to close from lowest fd"); return 0; } openssh-7.2p2/openbsd-compat/regress/opensslvertest.c010064400017500001750000000047301267006270000213070ustar00djmdjm/* * Copyright (c) 2014 Darren Tucker * * 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 #include int ssh_compatible_openssl(long, long); struct version_test { long headerver; long libver; int result; } version_tests[] = { /* built with 0.9.8b release headers */ { 0x0090802fL, 0x0090802fL, 1}, /* exact match */ { 0x0090802fL, 0x0090804fL, 1}, /* newer library fix version: ok */ { 0x0090802fL, 0x0090801fL, 1}, /* older library fix version: ok */ { 0x0090802fL, 0x0090702fL, 0}, /* older library minor version: NO */ { 0x0090802fL, 0x0090902fL, 0}, /* newer library minor version: NO */ { 0x0090802fL, 0x0080802fL, 0}, /* older library major version: NO */ { 0x0090802fL, 0x1000100fL, 0}, /* newer library major version: NO */ /* built with 1.0.1b release headers */ { 0x1000101fL, 0x1000101fL, 1},/* exact match */ { 0x1000101fL, 0x1000102fL, 1}, /* newer library patch version: ok */ { 0x1000101fL, 0x1000100fL, 1}, /* older library patch version: ok */ { 0x1000101fL, 0x1000201fL, 1}, /* newer library fix version: ok */ { 0x1000101fL, 0x1000001fL, 0}, /* older library fix version: NO */ { 0x1000101fL, 0x1010101fL, 0}, /* newer library minor version: NO */ { 0x1000101fL, 0x0000101fL, 0}, /* older library major version: NO */ { 0x1000101fL, 0x2000101fL, 0}, /* newer library major version: NO */ }; void fail(long hver, long lver, int result) { fprintf(stderr, "opensslver: header %lx library %lx != %d \n", hver, lver, result); exit(1); } int main(void) { unsigned int i; int res; long hver, lver; for (i = 0; i < sizeof(version_tests) / sizeof(version_tests[0]); i++) { hver = version_tests[i].headerver; lver = version_tests[i].libver; res = version_tests[i].result; if (ssh_compatible_openssl(hver, lver) != res) fail(hver, lver, res); } exit(0); } openssh-7.2p2/openbsd-compat/regress/snprintftest.c010064400017500001750000000036241267006270000207530ustar00djmdjm/* * Copyright (c) 2005 Darren Tucker * Copyright (c) 2005 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ #define BUFSZ 2048 #include #include #include #include #include static int failed = 0; static void fail(const char *m) { fprintf(stderr, "snprintftest: %s\n", m); failed = 1; } int x_snprintf(char *str, size_t count, const char *fmt, ...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } int main(void) { char b[5]; char *src; snprintf(b,5,"123456789"); if (b[4] != '\0') fail("snprintf does not correctly terminate long strings"); /* check for read overrun on unterminated string */ if ((src = malloc(BUFSZ)) == NULL) { fail("malloc failed"); } else { memset(src, 'a', BUFSZ); snprintf(b, sizeof(b), "%.*s", 1, src); if (strcmp(b, "a") != 0) fail("failed with length limit '%%.s'"); } /* check that snprintf and vsnprintf return sane values */ if (snprintf(b, 1, "%s %d", "hello", 12345) != 11) fail("snprintf does not return required length"); if (x_snprintf(b, 1, "%s %d", "hello", 12345) != 11) fail("vsnprintf does not return required length"); return failed; } openssh-7.2p2/openbsd-compat/regress/strduptest.c010064400017500001750000000020751267006270000204300ustar00djmdjm/* * Copyright (c) 2005 Darren Tucker * * 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 #include static int fail = 0; void test(const char *a) { char *b; b = strdup(a); if (b == 0) { fail = 1; return; } if (strcmp(a, b) != 0) fail = 1; free(b); } int main(void) { test(""); test("a"); test("\0"); test("abcdefghijklmnopqrstuvwxyz"); return fail; } openssh-7.2p2/openbsd-compat/regress/strtonumtest.c010064400017500001750000000047141267006270000210040ustar00djmdjm/* $OpenBSD: strtonumtest.c,v 1.1 2004/08/03 20:38:36 otto Exp $ */ /* * Copyright (c) 2004 Otto Moerbeek * * 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. */ /* OPENBSD ORIGINAL: regress/lib/libc/strtonum/strtonumtest.c */ #include #include #include /* LLONG_MAX is known as LONGLONG_MAX on AIX */ #if defined(LONGLONG_MAX) && !defined(LLONG_MAX) # define LLONG_MAX LONGLONG_MAX # define LLONG_MIN LONGLONG_MIN #endif /* LLONG_MAX is known as LONG_LONG_MAX on HP-UX */ #if defined(LONG_LONG_MAX) && !defined(LLONG_MAX) # define LLONG_MAX LONG_LONG_MAX # define LLONG_MIN LONG_LONG_MIN #endif long long strtonum(const char *, long long, long long, const char **); int fail; void test(const char *p, long long lb, long long ub, int ok) { long long val; const char *q; val = strtonum(p, lb, ub, &q); if (ok && q != NULL) { fprintf(stderr, "%s [%lld-%lld] ", p, lb, ub); fprintf(stderr, "NUMBER NOT ACCEPTED %s\n", q); fail = 1; } else if (!ok && q == NULL) { fprintf(stderr, "%s [%lld-%lld] %lld ", p, lb, ub, val); fprintf(stderr, "NUMBER ACCEPTED\n"); fail = 1; } } int main(int argc, char *argv[]) { test("1", 0, 10, 1); test("0", -2, 5, 1); test("0", 2, 5, 0); test("0", 2, LLONG_MAX, 0); test("-2", 0, LLONG_MAX, 0); test("0", -5, LLONG_MAX, 1); test("-3", -3, LLONG_MAX, 1); test("-9223372036854775808", LLONG_MIN, LLONG_MAX, 1); test("9223372036854775807", LLONG_MIN, LLONG_MAX, 1); test("-9223372036854775809", LLONG_MIN, LLONG_MAX, 0); test("9223372036854775808", LLONG_MIN, LLONG_MAX, 0); test("1000000000000000000000000", LLONG_MIN, LLONG_MAX, 0); test("-1000000000000000000000000", LLONG_MIN, LLONG_MAX, 0); test("-2", 10, -1, 0); test("-2", -10, -1, 1); test("-20", -10, -1, 0); test("20", -10, -1, 0); return (fail); } openssh-7.2p2/openbsd-compat/rmd160.c010064400017500001750000000273361267006270000155550ustar00djmdjm/* * 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. */ /* * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160", * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997, * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf */ #include "includes.h" #ifndef WITH_OPENSSL #include #ifdef HAVE_ENDIAN_H #include #endif #include #include #define PUT_64BIT_LE(cp, value) do { \ (cp)[7] = (value) >> 56; \ (cp)[6] = (value) >> 48; \ (cp)[5] = (value) >> 40; \ (cp)[4] = (value) >> 32; \ (cp)[3] = (value) >> 24; \ (cp)[2] = (value) >> 16; \ (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) #define PUT_32BIT_LE(cp, value) do { \ (cp)[3] = (value) >> 24; \ (cp)[2] = (value) >> 16; \ (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) #define H0 0x67452301U #define H1 0xEFCDAB89U #define H2 0x98BADCFEU #define H3 0x10325476U #define H4 0xC3D2E1F0U #define K0 0x00000000U #define K1 0x5A827999U #define K2 0x6ED9EBA1U #define K3 0x8F1BBCDCU #define K4 0xA953FD4EU #define KK0 0x50A28BE6U #define KK1 0x5C4DD124U #define KK2 0x6D703EF3U #define KK3 0x7A6D76E9U #define KK4 0x00000000U /* rotate x left n bits. */ #define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n)))) #define F0(x, y, z) ((x) ^ (y) ^ (z)) #define F1(x, y, z) (((x) & (y)) | ((~x) & (z))) #define F2(x, y, z) (((x) | (~y)) ^ (z)) #define F3(x, y, z) (((x) & (z)) | ((y) & (~z))) #define F4(x, y, z) ((x) ^ ((y) | (~z))) #define R(a, b, c, d, e, Fj, Kj, sj, rj) \ do { \ a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \ c = ROL(10, c); \ } while(0) #define X(i) x[i] static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void RMD160Init(RMD160_CTX *ctx) { ctx->count = 0; ctx->state[0] = H0; ctx->state[1] = H1; ctx->state[2] = H2; ctx->state[3] = H3; ctx->state[4] = H4; } void RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len) { size_t have, off, need; have = (ctx->count / 8) % RMD160_BLOCK_LENGTH; need = RMD160_BLOCK_LENGTH - have; ctx->count += 8 * len; off = 0; if (len >= need) { if (have) { memcpy(ctx->buffer + have, input, need); RMD160Transform(ctx->state, ctx->buffer); off = need; have = 0; } /* now the buffer is empty */ while (off + RMD160_BLOCK_LENGTH <= len) { RMD160Transform(ctx->state, input+off); off += RMD160_BLOCK_LENGTH; } } if (off < len) memcpy(ctx->buffer + have, input+off, len-off); } void RMD160Pad(RMD160_CTX *ctx) { u_int8_t size[8]; size_t padlen; PUT_64BIT_LE(size, ctx->count); /* * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from * PADDING plus 8 bytes for the size */ padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); if (padlen < 1 + 8) padlen += RMD160_BLOCK_LENGTH; RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ RMD160Update(ctx, size, 8); } void RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx) { int i; RMD160Pad(ctx); for (i = 0; i < 5; i++) PUT_32BIT_LE(digest + i*4, ctx->state[i]); memset(ctx, 0, sizeof (*ctx)); } void RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16]; #if BYTE_ORDER == LITTLE_ENDIAN memcpy(x, block, RMD160_BLOCK_LENGTH); #else int i; for (i = 0; i < 16; i++) x[i] = (u_int32_t)( (u_int32_t)(block[i*4 + 0]) | (u_int32_t)(block[i*4 + 1]) << 8 | (u_int32_t)(block[i*4 + 2]) << 16 | (u_int32_t)(block[i*4 + 3]) << 24); #endif a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* Round 1 */ R(a, b, c, d, e, F0, K0, 11, 0); R(e, a, b, c, d, F0, K0, 14, 1); R(d, e, a, b, c, F0, K0, 15, 2); R(c, d, e, a, b, F0, K0, 12, 3); R(b, c, d, e, a, F0, K0, 5, 4); R(a, b, c, d, e, F0, K0, 8, 5); R(e, a, b, c, d, F0, K0, 7, 6); R(d, e, a, b, c, F0, K0, 9, 7); R(c, d, e, a, b, F0, K0, 11, 8); R(b, c, d, e, a, F0, K0, 13, 9); R(a, b, c, d, e, F0, K0, 14, 10); R(e, a, b, c, d, F0, K0, 15, 11); R(d, e, a, b, c, F0, K0, 6, 12); R(c, d, e, a, b, F0, K0, 7, 13); R(b, c, d, e, a, F0, K0, 9, 14); R(a, b, c, d, e, F0, K0, 8, 15); /* #15 */ /* Round 2 */ R(e, a, b, c, d, F1, K1, 7, 7); R(d, e, a, b, c, F1, K1, 6, 4); R(c, d, e, a, b, F1, K1, 8, 13); R(b, c, d, e, a, F1, K1, 13, 1); R(a, b, c, d, e, F1, K1, 11, 10); R(e, a, b, c, d, F1, K1, 9, 6); R(d, e, a, b, c, F1, K1, 7, 15); R(c, d, e, a, b, F1, K1, 15, 3); R(b, c, d, e, a, F1, K1, 7, 12); R(a, b, c, d, e, F1, K1, 12, 0); R(e, a, b, c, d, F1, K1, 15, 9); R(d, e, a, b, c, F1, K1, 9, 5); R(c, d, e, a, b, F1, K1, 11, 2); R(b, c, d, e, a, F1, K1, 7, 14); R(a, b, c, d, e, F1, K1, 13, 11); R(e, a, b, c, d, F1, K1, 12, 8); /* #31 */ /* Round 3 */ R(d, e, a, b, c, F2, K2, 11, 3); R(c, d, e, a, b, F2, K2, 13, 10); R(b, c, d, e, a, F2, K2, 6, 14); R(a, b, c, d, e, F2, K2, 7, 4); R(e, a, b, c, d, F2, K2, 14, 9); R(d, e, a, b, c, F2, K2, 9, 15); R(c, d, e, a, b, F2, K2, 13, 8); R(b, c, d, e, a, F2, K2, 15, 1); R(a, b, c, d, e, F2, K2, 14, 2); R(e, a, b, c, d, F2, K2, 8, 7); R(d, e, a, b, c, F2, K2, 13, 0); R(c, d, e, a, b, F2, K2, 6, 6); R(b, c, d, e, a, F2, K2, 5, 13); R(a, b, c, d, e, F2, K2, 12, 11); R(e, a, b, c, d, F2, K2, 7, 5); R(d, e, a, b, c, F2, K2, 5, 12); /* #47 */ /* Round 4 */ R(c, d, e, a, b, F3, K3, 11, 1); R(b, c, d, e, a, F3, K3, 12, 9); R(a, b, c, d, e, F3, K3, 14, 11); R(e, a, b, c, d, F3, K3, 15, 10); R(d, e, a, b, c, F3, K3, 14, 0); R(c, d, e, a, b, F3, K3, 15, 8); R(b, c, d, e, a, F3, K3, 9, 12); R(a, b, c, d, e, F3, K3, 8, 4); R(e, a, b, c, d, F3, K3, 9, 13); R(d, e, a, b, c, F3, K3, 14, 3); R(c, d, e, a, b, F3, K3, 5, 7); R(b, c, d, e, a, F3, K3, 6, 15); R(a, b, c, d, e, F3, K3, 8, 14); R(e, a, b, c, d, F3, K3, 6, 5); R(d, e, a, b, c, F3, K3, 5, 6); R(c, d, e, a, b, F3, K3, 12, 2); /* #63 */ /* Round 5 */ R(b, c, d, e, a, F4, K4, 9, 4); R(a, b, c, d, e, F4, K4, 15, 0); R(e, a, b, c, d, F4, K4, 5, 5); R(d, e, a, b, c, F4, K4, 11, 9); R(c, d, e, a, b, F4, K4, 6, 7); R(b, c, d, e, a, F4, K4, 8, 12); R(a, b, c, d, e, F4, K4, 13, 2); R(e, a, b, c, d, F4, K4, 12, 10); R(d, e, a, b, c, F4, K4, 5, 14); R(c, d, e, a, b, F4, K4, 12, 1); R(b, c, d, e, a, F4, K4, 13, 3); R(a, b, c, d, e, F4, K4, 14, 8); R(e, a, b, c, d, F4, K4, 11, 11); R(d, e, a, b, c, F4, K4, 8, 6); R(c, d, e, a, b, F4, K4, 5, 15); R(b, c, d, e, a, F4, K4, 6, 13); /* #79 */ aa = a ; bb = b; cc = c; dd = d; ee = e; a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* Parallel round 1 */ R(a, b, c, d, e, F4, KK0, 8, 5); R(e, a, b, c, d, F4, KK0, 9, 14); R(d, e, a, b, c, F4, KK0, 9, 7); R(c, d, e, a, b, F4, KK0, 11, 0); R(b, c, d, e, a, F4, KK0, 13, 9); R(a, b, c, d, e, F4, KK0, 15, 2); R(e, a, b, c, d, F4, KK0, 15, 11); R(d, e, a, b, c, F4, KK0, 5, 4); R(c, d, e, a, b, F4, KK0, 7, 13); R(b, c, d, e, a, F4, KK0, 7, 6); R(a, b, c, d, e, F4, KK0, 8, 15); R(e, a, b, c, d, F4, KK0, 11, 8); R(d, e, a, b, c, F4, KK0, 14, 1); R(c, d, e, a, b, F4, KK0, 14, 10); R(b, c, d, e, a, F4, KK0, 12, 3); R(a, b, c, d, e, F4, KK0, 6, 12); /* #15 */ /* Parallel round 2 */ R(e, a, b, c, d, F3, KK1, 9, 6); R(d, e, a, b, c, F3, KK1, 13, 11); R(c, d, e, a, b, F3, KK1, 15, 3); R(b, c, d, e, a, F3, KK1, 7, 7); R(a, b, c, d, e, F3, KK1, 12, 0); R(e, a, b, c, d, F3, KK1, 8, 13); R(d, e, a, b, c, F3, KK1, 9, 5); R(c, d, e, a, b, F3, KK1, 11, 10); R(b, c, d, e, a, F3, KK1, 7, 14); R(a, b, c, d, e, F3, KK1, 7, 15); R(e, a, b, c, d, F3, KK1, 12, 8); R(d, e, a, b, c, F3, KK1, 7, 12); R(c, d, e, a, b, F3, KK1, 6, 4); R(b, c, d, e, a, F3, KK1, 15, 9); R(a, b, c, d, e, F3, KK1, 13, 1); R(e, a, b, c, d, F3, KK1, 11, 2); /* #31 */ /* Parallel round 3 */ R(d, e, a, b, c, F2, KK2, 9, 15); R(c, d, e, a, b, F2, KK2, 7, 5); R(b, c, d, e, a, F2, KK2, 15, 1); R(a, b, c, d, e, F2, KK2, 11, 3); R(e, a, b, c, d, F2, KK2, 8, 7); R(d, e, a, b, c, F2, KK2, 6, 14); R(c, d, e, a, b, F2, KK2, 6, 6); R(b, c, d, e, a, F2, KK2, 14, 9); R(a, b, c, d, e, F2, KK2, 12, 11); R(e, a, b, c, d, F2, KK2, 13, 8); R(d, e, a, b, c, F2, KK2, 5, 12); R(c, d, e, a, b, F2, KK2, 14, 2); R(b, c, d, e, a, F2, KK2, 13, 10); R(a, b, c, d, e, F2, KK2, 13, 0); R(e, a, b, c, d, F2, KK2, 7, 4); R(d, e, a, b, c, F2, KK2, 5, 13); /* #47 */ /* Parallel round 4 */ R(c, d, e, a, b, F1, KK3, 15, 8); R(b, c, d, e, a, F1, KK3, 5, 6); R(a, b, c, d, e, F1, KK3, 8, 4); R(e, a, b, c, d, F1, KK3, 11, 1); R(d, e, a, b, c, F1, KK3, 14, 3); R(c, d, e, a, b, F1, KK3, 14, 11); R(b, c, d, e, a, F1, KK3, 6, 15); R(a, b, c, d, e, F1, KK3, 14, 0); R(e, a, b, c, d, F1, KK3, 6, 5); R(d, e, a, b, c, F1, KK3, 9, 12); R(c, d, e, a, b, F1, KK3, 12, 2); R(b, c, d, e, a, F1, KK3, 9, 13); R(a, b, c, d, e, F1, KK3, 12, 9); R(e, a, b, c, d, F1, KK3, 5, 7); R(d, e, a, b, c, F1, KK3, 15, 10); R(c, d, e, a, b, F1, KK3, 8, 14); /* #63 */ /* Parallel round 5 */ R(b, c, d, e, a, F0, KK4, 8, 12); R(a, b, c, d, e, F0, KK4, 5, 15); R(e, a, b, c, d, F0, KK4, 12, 10); R(d, e, a, b, c, F0, KK4, 9, 4); R(c, d, e, a, b, F0, KK4, 12, 1); R(b, c, d, e, a, F0, KK4, 5, 5); R(a, b, c, d, e, F0, KK4, 14, 8); R(e, a, b, c, d, F0, KK4, 6, 7); R(d, e, a, b, c, F0, KK4, 8, 6); R(c, d, e, a, b, F0, KK4, 13, 2); R(b, c, d, e, a, F0, KK4, 6, 13); R(a, b, c, d, e, F0, KK4, 5, 14); R(e, a, b, c, d, F0, KK4, 15, 0); R(d, e, a, b, c, F0, KK4, 13, 3); R(c, d, e, a, b, F0, KK4, 11, 9); R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */ t = state[1] + cc + d; state[1] = state[2] + dd + e; state[2] = state[3] + ee + a; state[3] = state[4] + aa + b; state[4] = state[0] + bb + c; state[0] = t; } #endif /* !WITH_OPENSSL */ openssh-7.2p2/openbsd-compat/rmd160.h010064400017500001750000000054711267006270000155560ustar00djmdjm/* $OpenBSD: rmd160.h,v 1.17 2012/12/05 23:19:57 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. */ #ifndef _RMD160_H #define _RMD160_H #ifndef WITH_OPENSSL #define RMD160_BLOCK_LENGTH 64 #define RMD160_DIGEST_LENGTH 20 #define RMD160_DIGEST_STRING_LENGTH (RMD160_DIGEST_LENGTH * 2 + 1) /* RMD160 context. */ typedef struct RMD160Context { u_int32_t state[5]; /* state */ u_int64_t count; /* number of bits, mod 2^64 */ u_int8_t buffer[RMD160_BLOCK_LENGTH]; /* input buffer */ } RMD160_CTX; void RMD160Init(RMD160_CTX *); void RMD160Transform(u_int32_t [5], const u_int8_t [RMD160_BLOCK_LENGTH]) __attribute__((__bounded__(__minbytes__,1,5))) __attribute__((__bounded__(__minbytes__,2,RMD160_BLOCK_LENGTH))); void RMD160Update(RMD160_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void RMD160Pad(RMD160_CTX *); void RMD160Final(u_int8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *) __attribute__((__bounded__(__minbytes__,1,RMD160_DIGEST_LENGTH))); char *RMD160End(RMD160_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); char *RMD160File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); char *RMD160FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); char *RMD160Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,RMD160_DIGEST_STRING_LENGTH))); #endif /* !WITH_OPENSSL */ #endif /* _RMD160_H */ openssh-7.2p2/openbsd-compat/rresvport.c010064400017500001750000000057441267006270000166110ustar00djmdjm/* $OpenBSD: rresvport.c,v 1.9 2005/11/10 10:00:17 espie Exp $ */ /* * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. * Copyright (c) 1983, 1993, 1994 * 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. */ /* OPENBSD ORIGINAL: lib/libc/net/rresvport.c */ #include "includes.h" #ifndef HAVE_RRESVPORT_AF #include #include #include #include #include #include #include #include #if 0 int rresvport(int *alport) { return rresvport_af(alport, AF_INET); } #endif int rresvport_af(int *alport, sa_family_t af) { struct sockaddr_storage ss; struct sockaddr *sa; u_int16_t *portp; int s; socklen_t salen; memset(&ss, '\0', sizeof ss); sa = (struct sockaddr *)&ss; switch (af) { case AF_INET: salen = sizeof(struct sockaddr_in); portp = &((struct sockaddr_in *)sa)->sin_port; break; case AF_INET6: salen = sizeof(struct sockaddr_in6); portp = &((struct sockaddr_in6 *)sa)->sin6_port; break; default: errno = EPFNOSUPPORT; return (-1); } sa->sa_family = af; s = socket(af, SOCK_STREAM, 0); if (s < 0) return (-1); *portp = htons(*alport); if (*alport < IPPORT_RESERVED - 1) { if (bind(s, sa, salen) >= 0) return (s); if (errno != EADDRINUSE) { (void)close(s); return (-1); } } *portp = 0; sa->sa_family = af; if (bindresvport_sa(s, sa) == -1) { (void)close(s); return (-1); } *alport = ntohs(*portp); return (s); } #endif /* HAVE_RRESVPORT_AF */ openssh-7.2p2/openbsd-compat/setenv.c010064400017500001750000000134141267006270000160400ustar00djmdjm/* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */ /* * Copyright (c) 1987 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/setenv.c */ #include "includes.h" #if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) #include #include #include extern char **environ; static char **lastenv; /* last value of environ */ /* OpenSSH Portable: __findenv is from getenv.c rev 1.8, made static */ /* * __findenv -- * Returns pointer to value associated with name, if any, else NULL. * Starts searching within the environmental array at offset. * Sets offset to be the offset of the name/value combination in the * environmental array, for use by putenv(3), setenv(3) and unsetenv(3). * Explicitly removes '=' in argument name. * * This routine *should* be a static; don't use it. */ static char * __findenv(const char *name, int len, int *offset) { extern char **environ; int i; const char *np; char **p, *cp; if (name == NULL || environ == NULL) return (NULL); for (p = environ + *offset; (cp = *p) != NULL; ++p) { for (np = name, i = len; i && *cp; i--) if (*cp++ != *np++) break; if (i == 0 && *cp++ == '=') { *offset = p - environ; return (cp); } } return (NULL); } #if 0 /* nothing uses putenv */ /* * putenv -- * Add a name=value string directly to the environmental, replacing * any current value. */ int putenv(char *str) { char **P, *cp; size_t cnt; int offset = 0; for (cp = str; *cp && *cp != '='; ++cp) ; if (*cp != '=') { errno = EINVAL; return (-1); /* missing `=' in string */ } if (__findenv(str, (int)(cp - str), &offset) != NULL) { environ[offset++] = str; /* could be set multiple times */ while (__findenv(str, (int)(cp - str), &offset)) { for (P = &environ[offset];; ++P) if (!(*P = *(P + 1))) break; } return (0); } /* create new slot for string */ for (P = environ; *P != NULL; P++) ; cnt = P - environ; P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); if (!P) return (-1); if (lastenv != environ) memcpy(P, environ, cnt * sizeof(char *)); lastenv = environ = P; environ[cnt] = str; environ[cnt + 1] = NULL; return (0); } #endif #ifndef HAVE_SETENV /* * setenv -- * Set the value of the environmental variable "name" to be * "value". If rewrite is set, replace any current value. */ int setenv(const char *name, const char *value, int rewrite) { char *C, **P; const char *np; int l_value, offset = 0; for (np = name; *np && *np != '='; ++np) ; #ifdef notyet if (*np) { errno = EINVAL; return (-1); /* has `=' in name */ } #endif l_value = strlen(value); if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { int tmpoff = offset + 1; if (!rewrite) return (0); #if 0 /* XXX - existing entry may not be writable */ if (strlen(C) >= l_value) { /* old larger; copy over */ while ((*C++ = *value++)) ; return (0); } #endif /* could be set multiple times */ while (__findenv(name, (int)(np - name), &tmpoff)) { for (P = &environ[tmpoff];; ++P) if (!(*P = *(P + 1))) break; } } else { /* create new slot */ size_t cnt; for (P = environ; *P != NULL; P++) ; cnt = P - environ; P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); if (!P) return (-1); if (lastenv != environ) memcpy(P, environ, cnt * sizeof(char *)); lastenv = environ = P; offset = cnt; environ[cnt + 1] = NULL; } if (!(environ[offset] = /* name + `=' + value */ malloc((size_t)((int)(np - name) + l_value + 2)))) return (-1); for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) ; for (*C++ = '='; (*C++ = *value++); ) ; return (0); } #endif /* HAVE_SETENV */ #ifndef HAVE_UNSETENV /* * unsetenv(name) -- * Delete environmental variable "name". */ int unsetenv(const char *name) { char **P; const char *np; int offset = 0; if (!name || !*name) { errno = EINVAL; return (-1); } for (np = name; *np && *np != '='; ++np) ; if (*np) { errno = EINVAL; return (-1); /* has `=' in name */ } /* could be set multiple times */ while (__findenv(name, (int)(np - name), &offset)) { for (P = &environ[offset];; ++P) if (!(*P = *(P + 1))) break; } return (0); } #endif /* HAVE_UNSETENV */ #endif /* !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) */ openssh-7.2p2/openbsd-compat/setproctitle.c010064400017500001750000000110601267006270000172500ustar00djmdjm/* Based on conf.c from UCB sendmail 8.8.8 */ /* * Copyright 2003 Damien Miller * Copyright (c) 1983, 1995-1997 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. */ #include "includes.h" #ifndef HAVE_SETPROCTITLE #include #include #include #ifdef HAVE_SYS_PSTAT_H #include #endif #include #include #define SPT_NONE 0 /* don't use it at all */ #define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ #define SPT_REUSEARGV 2 /* cover argv with title information */ #ifndef SPT_TYPE # define SPT_TYPE SPT_NONE #endif #ifndef SPT_PADCHAR # define SPT_PADCHAR '\0' #endif #if SPT_TYPE == SPT_REUSEARGV static char *argv_start = NULL; static size_t argv_env_len = 0; #endif #endif /* HAVE_SETPROCTITLE */ void compat_init_setproctitle(int argc, char *argv[]) { #if !defined(HAVE_SETPROCTITLE) && \ defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV extern char **environ; char *lastargv = NULL; char **envp = environ; int i; /* * NB: This assumes that argv has already been copied out of the * way. This is true for sshd, but may not be true for other * programs. Beware. */ if (argc == 0 || argv[0] == NULL) return; /* Fail if we can't allocate room for the new environment */ for (i = 0; envp[i] != NULL; i++) ; if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { environ = envp; /* put it back */ return; } /* * Find the last argv string or environment variable within * our process memory area. */ for (i = 0; i < argc; i++) { if (lastargv == NULL || lastargv + 1 == argv[i]) lastargv = argv[i] + strlen(argv[i]); } for (i = 0; envp[i] != NULL; i++) { if (lastargv + 1 == envp[i]) lastargv = envp[i] + strlen(envp[i]); } argv[1] = NULL; argv_start = argv[0]; argv_env_len = lastargv - argv[0] - 1; /* * Copy environment * XXX - will truncate env on strdup fail */ for (i = 0; envp[i] != NULL; i++) environ[i] = strdup(envp[i]); environ[i] = NULL; #endif /* SPT_REUSEARGV */ } #ifndef HAVE_SETPROCTITLE void setproctitle(const char *fmt, ...) { #if SPT_TYPE != SPT_NONE va_list ap; char buf[1024], ptitle[1024]; size_t len; int r; extern char *__progname; #if SPT_TYPE == SPT_PSTAT union pstun pst; #endif #if SPT_TYPE == SPT_REUSEARGV if (argv_env_len <= 0) return; #endif strlcpy(buf, __progname, sizeof(buf)); r = -1; va_start(ap, fmt); if (fmt != NULL) { len = strlcat(buf, ": ", sizeof(buf)); if (len < sizeof(buf)) r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); } va_end(ap); if (r == -1 || (size_t)r >= sizeof(buf) - len) return; strnvis(ptitle, buf, sizeof(ptitle), VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); #if SPT_TYPE == SPT_PSTAT pst.pst_command = ptitle; pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); #elif SPT_TYPE == SPT_REUSEARGV /* debug("setproctitle: copy \"%s\" into len %d", buf, argv_env_len); */ len = strlcpy(argv_start, ptitle, argv_env_len); for(; len < argv_env_len; len++) argv_start[len] = SPT_PADCHAR; #endif #endif /* SPT_NONE */ } #endif /* HAVE_SETPROCTITLE */ openssh-7.2p2/openbsd-compat/sha1.c010064400017500001750000000122641267006270000153720ustar00djmdjm/* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $ */ /* * SHA-1 in C * By Steve Reid * 100% Public Domain * * Test Vectors (from FIPS PUB 180-1) * "abc" * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 * A million repetitions of "a" * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #include "includes.h" #ifndef WITH_OPENSSL #include #include #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* * blk0() and blk() perform the initial expand. * I got the idea of expanding during the round function from SSLeay */ #if BYTE_ORDER == LITTLE_ENDIAN # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |(rol(block->l[i],8)&0x00FF00FF)) #else # define blk0(i) block->l[i] #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); typedef union { u_int8_t c[64]; u_int32_t l[16]; } CHAR64LONG16; /* * Hash a single 512-bit block. This is the core of the algorithm. */ void SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e; u_int8_t workspace[SHA1_BLOCK_LENGTH]; CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; } /* * SHA1Init - Initialize new context */ void SHA1Init(SHA1_CTX *context) { /* SHA1 initialization constants */ context->count = 0; context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; } /* * Run your data through this. */ void SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) { size_t i, j; j = (size_t)((context->count >> 3) & 63); context->count += (len << 3); if ((j + len) > 63) { (void)memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) SHA1Transform(context->state, (u_int8_t *)&data[i]); j = 0; } else { i = 0; } (void)memcpy(&context->buffer[j], &data[i], len - i); } /* * Add padding and return the message digest. */ void SHA1Pad(SHA1_CTX *context) { u_int8_t finalcount[8]; u_int i; for (i = 0; i < 8; i++) { finalcount[i] = (u_int8_t)((context->count >> ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ } SHA1Update(context, (u_int8_t *)"\200", 1); while ((context->count & 504) != 448) SHA1Update(context, (u_int8_t *)"\0", 1); SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ } void SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) { u_int i; SHA1Pad(context); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { digest[i] = (u_int8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } memset(context, 0, sizeof(*context)); } #endif /* !WITH_OPENSSL */ openssh-7.2p2/openbsd-compat/sha1.h010064400017500001750000000043561267006270000154020ustar00djmdjm/* $OpenBSD: sha1.h,v 1.24 2012/12/05 23:19:57 deraadt Exp $ */ /* * SHA-1 in C * By Steve Reid * 100% Public Domain */ #ifndef _SHA1_H #define _SHA1_H #ifndef WITH_OPENSSL #define SHA1_BLOCK_LENGTH 64 #define SHA1_DIGEST_LENGTH 20 #define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) typedef struct { u_int32_t state[5]; u_int64_t count; u_int8_t buffer[SHA1_BLOCK_LENGTH]; } SHA1_CTX; void SHA1Init(SHA1_CTX *); void SHA1Pad(SHA1_CTX *); void SHA1Transform(u_int32_t [5], const u_int8_t [SHA1_BLOCK_LENGTH]) __attribute__((__bounded__(__minbytes__,1,5))) __attribute__((__bounded__(__minbytes__,2,SHA1_BLOCK_LENGTH))); void SHA1Update(SHA1_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void SHA1Final(u_int8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH))); char *SHA1End(SHA1_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); char *SHA1File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); char *SHA1FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); char *SHA1Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA1_DIGEST_STRING_LENGTH))); #define HTONDIGEST(x) do { \ x[0] = htonl(x[0]); \ x[1] = htonl(x[1]); \ x[2] = htonl(x[2]); \ x[3] = htonl(x[3]); \ x[4] = htonl(x[4]); } while (0) #define NTOHDIGEST(x) do { \ x[0] = ntohl(x[0]); \ x[1] = ntohl(x[1]); \ x[2] = ntohl(x[2]); \ x[3] = ntohl(x[3]); \ x[4] = ntohl(x[4]); } while (0) #endif /* !WITH_OPENSSL */ #endif /* _SHA1_H */ openssh-7.2p2/openbsd-compat/sha2.c010064400017500001750000000616041267006270000153750ustar00djmdjm/* from OpenBSD: sha2.c,v 1.11 2005/08/08 08:05:35 espie Exp */ /* * FILE: sha2.c * AUTHOR: Aaron D. Gifford * * Copyright (c) 2000-2001, Aaron D. Gifford * 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 copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) 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. * * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ */ /* OPENBSD ORIGINAL: lib/libc/hash/sha2.c */ #include "includes.h" #ifdef WITH_OPENSSL # include # if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) # define _NEED_SHA2 1 # endif #else # define _NEED_SHA2 1 #endif #if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) #include /* * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * #define SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivilent. * * If your system does not define the above, then you can do so by * hand like this: * * #define LITTLE_ENDIAN 1234 * #define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * #define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * #define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /*** ENDIAN SPECIFIC COPY MACROS **************************************/ #define BE_8_TO_32(dst, cp) do { \ (dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \ ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \ } while(0) #define BE_8_TO_64(dst, cp) do { \ (dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \ ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \ ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \ ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \ } while (0) #define BE_64_TO_8(cp, src) do { \ (cp)[0] = (src) >> 56; \ (cp)[1] = (src) >> 48; \ (cp)[2] = (src) >> 40; \ (cp)[3] = (src) >> 32; \ (cp)[4] = (src) >> 24; \ (cp)[5] = (src) >> 16; \ (cp)[6] = (src) >> 8; \ (cp)[7] = (src); \ } while (0) #define BE_32_TO_8(cp, src) do { \ (cp)[0] = (src) >> 24; \ (cp)[1] = (src) >> 16; \ (cp)[2] = (src) >> 8; \ (cp)[3] = (src); \ } while (0) /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) do { \ (w)[0] += (u_int64_t)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } while (0) /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ const static u_int32_t K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ const static u_int32_t sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ const static u_int64_t K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* Initial hash value H for SHA-384 */ const static u_int64_t sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL }; /* Initial hash value H for SHA-512 */ const static u_int64_t sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; /*** SHA-256: *********************************************************/ void SHA256_Init(SHA256_CTX *context) { if (context == NULL) return; memcpy(context->state, sha256_initial_hash_value, sizeof(sha256_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); context->bitcount = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \ BE_8_TO_32(W256[j], data); \ data += 4; \ T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ j++; \ } while(0) #define ROUND256(a,b,c,d,e,f,g,h) do { \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ j++; \ } while(0) void SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t T1, W256[16]; int j; /* Initialize registers with the prev. intermediate value */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; f = state[5]; g = state[6]; h = state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 63: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) { u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t T1, T2, W256[16]; int j; /* Initialize registers with the prev. intermediate value */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; f = state[5]; g = state[6]; h = state[7]; j = 0; do { BE_8_TO_32(W256[j], data); data += 4; /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) { size_t freespace, usedspace; /* Calling with no data is valid (we do nothing) */ if (len == 0) return; usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ memcpy(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; SHA256_Transform(context->state, context->buffer); } else { /* The buffer is not yet full */ memcpy(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA256_Transform(context->state, data); context->bitcount += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ memcpy(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } void SHA256_Pad(SHA256_CTX *context) { unsigned int usedspace; usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA256_BLOCK_LENGTH) { memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA256_Transform(context->state, context->buffer); /* Prepare for last transform: */ memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); } } else { /* Set-up for the last transform: */ memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits) in big endian format: */ BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], context->bitcount); /* Final transform: */ SHA256_Transform(context->state, context->buffer); /* Clean up: */ usedspace = 0; } void SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context) { SHA256_Pad(context); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN int i; /* Convert TO host byte order */ for (i = 0; i < 8; i++) BE_32_TO_8(digest + i * 4, context->state[i]); #else memcpy(digest, context->state, SHA256_DIGEST_LENGTH); #endif memset(context, 0, sizeof(*context)); } } /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX *context) { if (context == NULL) return; memcpy(context->state, sha512_initial_hash_value, sizeof(sha512_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \ BE_8_TO_64(W512[j], data); \ data += 8; \ T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \ (d) += T1; \ (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ j++; \ } while(0) #define ROUND512(a,b,c,d,e,f,g,h) do { \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ j++; \ } while(0) void SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t T1, W512[16]; int j; /* Initialize registers with the prev. intermediate value */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; f = state[5]; g = state[6]; h = state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t T1, T2, W512[16]; int j; /* Initialize registers with the prev. intermediate value */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; f = state[5]; g = state[6]; h = state[7]; j = 0; do { BE_8_TO_64(W512[j], data); data += 8; /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) { size_t freespace, usedspace; /* Calling with no data is valid (we do nothing) */ if (len == 0) return; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ memcpy(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; SHA512_Transform(context->state, context->buffer); } else { /* The buffer is not yet full */ memcpy(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA512_Transform(context->state, data); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ memcpy(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } void SHA512_Pad(SHA512_CTX *context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA512_BLOCK_LENGTH) { memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA512_Transform(context->state, context->buffer); /* And set-up for the last transform: */ memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); } } else { /* Prepare for final transform: */ memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits) in big endian format: */ BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], context->bitcount[1]); BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8], context->bitcount[0]); /* Final transform: */ SHA512_Transform(context->state, context->buffer); /* Clean up: */ usedspace = 0; } void SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) { SHA512_Pad(context); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN int i; /* Convert TO host byte order */ for (i = 0; i < 8; i++) BE_64_TO_8(digest + i * 8, context->state[i]); #else memcpy(digest, context->state, SHA512_DIGEST_LENGTH); #endif memset(context, 0, sizeof(*context)); } } /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX *context) { if (context == NULL) return; memcpy(context->state, sha384_initial_hash_value, sizeof(sha384_initial_hash_value)); memset(context->buffer, 0, sizeof(context->buffer)); context->bitcount[0] = context->bitcount[1] = 0; } #if 0 __weak_alias(SHA384_Transform, SHA512_Transform); __weak_alias(SHA384_Update, SHA512_Update); __weak_alias(SHA384_Pad, SHA512_Pad); #endif void SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) { return SHA512_Transform(state, data); } void SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) { SHA512_Update(context, data, len); } void SHA384_Pad(SHA512_CTX *context) { SHA512_Pad(context); } void SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) { SHA384_Pad(context); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != NULL) { #if BYTE_ORDER == LITTLE_ENDIAN int i; /* Convert TO host byte order */ for (i = 0; i < 6; i++) BE_64_TO_8(digest + i * 8, context->state[i]); #else memcpy(digest, context->state, SHA384_DIGEST_LENGTH); #endif } /* Zero out state data */ memset(context, 0, sizeof(*context)); } #endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ openssh-7.2p2/openbsd-compat/sha2.h010064400017500001750000000132361267006270000154000ustar00djmdjm/* OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp */ /* * FILE: sha2.h * AUTHOR: Aaron D. Gifford * * Copyright (c) 2000-2001, Aaron D. Gifford * 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 copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) 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. * * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ */ /* OPENBSD ORIGINAL: include/sha2.h */ #ifndef _SSHSHA2_H #define _SSHSHA2_H #include "includes.h" #ifdef WITH_OPENSSL # include # if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) # define _NEED_SHA2 1 # endif #else # define _NEED_SHA2 1 #endif #if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA384_BLOCK_LENGTH 128 #define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ typedef struct _SHA256_CTX { u_int32_t state[8]; u_int64_t bitcount; u_int8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { u_int64_t state[8]; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; typedef SHA512_CTX SHA384_CTX; void SHA256_Init(SHA256_CTX *); void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); void SHA256_Update(SHA256_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void SHA256_Pad(SHA256_CTX *); void SHA256_Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA256_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH))); char *SHA256_End(SHA256_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); char *SHA256_File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); char *SHA256_FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); char *SHA256_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); void SHA384_Init(SHA384_CTX *); void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void SHA384_Pad(SHA384_CTX *); void SHA384_Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA384_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH))); char *SHA384_End(SHA384_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); char *SHA384_File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); char *SHA384_FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); char *SHA384_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); void SHA512_Init(SHA512_CTX *); void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); void SHA512_Update(SHA512_CTX *, const u_int8_t *, size_t) __attribute__((__bounded__(__string__,2,3))); void SHA512_Pad(SHA512_CTX *); void SHA512_Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA512_CTX *) __attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH))); char *SHA512_End(SHA512_CTX *, char *) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); char *SHA512_File(const char *, char *) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); char *SHA512_FileChunk(const char *, char *, off_t, off_t) __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); char *SHA512_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); #endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ #endif /* _SSHSHA2_H */ openssh-7.2p2/openbsd-compat/sigact.c010064400017500001750000000075131267006270000160110ustar00djmdjm/* $OpenBSD: sigaction.c,v 1.4 2001/01/22 18:01:48 millert Exp $ */ /**************************************************************************** * Copyright (c) 1998,2000 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. * ****************************************************************************/ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * ****************************************************************************/ /* OPENBSD ORIGINAL: lib/libcurses/base/sigaction.c */ #include "includes.h" #include #include #include "sigact.h" /* This file provides sigaction() emulation using sigvec() */ /* Use only if this is non POSIX system */ #if !HAVE_SIGACTION && HAVE_SIGVEC int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) { return sigvec(sig, sigact ? &sigact->sv : NULL, osigact ? &osigact->sv : NULL); } int sigemptyset (sigset_t *mask) { if (!mask) { errno = EINVAL; return -1; } *mask = 0; return 0; } int sigprocmask (int mode, sigset_t *mask, sigset_t *omask) { sigset_t current = sigsetmask(0); if (!mask) { errno = EINVAL; return -1; } if (omask) *omask = current; if (mode == SIG_BLOCK) current |= *mask; else if (mode == SIG_UNBLOCK) current &= ~*mask; else if (mode == SIG_SETMASK) current = *mask; sigsetmask(current); return 0; } int sigsuspend (sigset_t *mask) { if (!mask) { errno = EINVAL; return -1; } return sigpause(*mask); } int sigdelset (sigset_t *mask, int sig) { if (!mask) { errno = EINVAL; return -1; } *mask &= ~sigmask(sig); return 0; } int sigaddset (sigset_t *mask, int sig) { if (!mask) { errno = EINVAL; return -1; } *mask |= sigmask(sig); return 0; } int sigismember (sigset_t *mask, int sig) { if (!mask) { errno = EINVAL; return -1; } return (*mask & sigmask(sig)) != 0; } #endif openssh-7.2p2/openbsd-compat/sigact.h010064400017500001750000000072501267006270000160140ustar00djmdjm/* $OpenBSD: SigAction.h,v 1.3 2001/01/22 18:01:32 millert Exp $ */ /**************************************************************************** * Copyright (c) 1998,2000 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. * ****************************************************************************/ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * ****************************************************************************/ /* * $From: SigAction.h,v 1.6 2000/12/10 02:36:10 tom Exp $ * * This file exists to handle non-POSIX systems which don't have , * and usually no sigaction() nor */ /* OPENBSD ORIGINAL: lib/libcurses/SigAction.h */ #ifndef _SIGACTION_H #define _SIGACTION_H #if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) #undef SIG_BLOCK #define SIG_BLOCK 00 #undef SIG_UNBLOCK #define SIG_UNBLOCK 01 #undef SIG_SETMASK #define SIG_SETMASK 02 /* * is in the Linux 1.2.8 + gcc 2.7.0 configuration, * and is useful for testing this header file. */ #if HAVE_BSD_SIGNAL_H # include #endif struct sigaction { struct sigvec sv; }; typedef unsigned long sigset_t; #undef sa_mask #define sa_mask sv.sv_mask #undef sa_handler #define sa_handler sv.sv_handler #undef sa_flags #define sa_flags sv.sv_flags int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); int sigprocmask (int how, sigset_t *mask, sigset_t *omask); int sigemptyset (sigset_t *mask); int sigsuspend (sigset_t *mask); int sigdelset (sigset_t *mask, int sig); int sigaddset (sigset_t *mask, int sig); #endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ #endif /* !defined(_SIGACTION_H) */ openssh-7.2p2/openbsd-compat/strlcat.c010064400017500001750000000034161267006270000162110ustar00djmdjm/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ #include "includes.h" #ifndef HAVE_STRLCAT #include #include /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ size_t strlcat(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } #endif /* !HAVE_STRLCAT */ openssh-7.2p2/openbsd-compat/strlcpy.c010064400017500001750000000032241267006270000162320ustar00djmdjm/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ #include "includes.h" #ifndef HAVE_STRLCPY #include #include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif /* !HAVE_STRLCPY */ openssh-7.2p2/openbsd-compat/strmode.c010064400017500001750000000066031267006270000162130ustar00djmdjm/* $OpenBSD: strmode.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ /*- * Copyright (c) 1990 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. */ /* OPENBSD ORIGINAL: lib/libc/string/strmode.c */ #include "includes.h" #ifndef HAVE_STRMODE #include #include #include /* XXX mode should be mode_t */ void strmode(int mode, char *p) { /* print type */ switch (mode & S_IFMT) { case S_IFDIR: /* directory */ *p++ = 'd'; break; case S_IFCHR: /* character special */ *p++ = 'c'; break; case S_IFBLK: /* block special */ *p++ = 'b'; break; case S_IFREG: /* regular */ *p++ = '-'; break; case S_IFLNK: /* symbolic link */ *p++ = 'l'; break; #ifdef S_IFSOCK case S_IFSOCK: /* socket */ *p++ = 's'; break; #endif #ifdef S_IFIFO case S_IFIFO: /* fifo */ *p++ = 'p'; break; #endif default: /* unknown */ *p++ = '?'; break; } /* usr */ if (mode & S_IRUSR) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWUSR) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXUSR | S_ISUID)) { case 0: *p++ = '-'; break; case S_IXUSR: *p++ = 'x'; break; case S_ISUID: *p++ = 'S'; break; case S_IXUSR | S_ISUID: *p++ = 's'; break; } /* group */ if (mode & S_IRGRP) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWGRP) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXGRP | S_ISGID)) { case 0: *p++ = '-'; break; case S_IXGRP: *p++ = 'x'; break; case S_ISGID: *p++ = 'S'; break; case S_IXGRP | S_ISGID: *p++ = 's'; break; } /* other */ if (mode & S_IROTH) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWOTH) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXOTH | S_ISVTX)) { case 0: *p++ = '-'; break; case S_IXOTH: *p++ = 'x'; break; case S_ISVTX: *p++ = 'T'; break; case S_IXOTH | S_ISVTX: *p++ = 't'; break; } *p++ = ' '; /* will be a '+' if ACL's implemented */ *p = '\0'; } #endif openssh-7.2p2/openbsd-compat/strnlen.c010064400017500001750000000022271267006270000162210ustar00djmdjm/* $OpenBSD: strnlen.c,v 1.3 2010/06/02 12:58:12 millert Exp $ */ /* * Copyright (c) 2010 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* OPENBSD ORIGINAL: lib/libc/string/strnlen.c */ #include "config.h" #ifndef HAVE_STRNLEN #include #include size_t strnlen(const char *str, size_t maxlen) { const char *cp; for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) ; return (size_t)(cp - str); } #endif openssh-7.2p2/openbsd-compat/strptime.c010064400017500001750000000224411267006270000164030ustar00djmdjm/* $OpenBSD: strptime.c,v 1.12 2008/06/26 05:42:05 ray Exp $ */ /* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code was contributed to The NetBSD Foundation by Klaus Klein. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /* OPENBSD ORIGINAL: lib/libc/time/strptime.c */ #include "includes.h" #ifndef HAVE_STRPTIME #define TM_YEAR_BASE 1900 /* from tzfile.h */ #include #include #include #include /* #define _ctloc(x) (_CurrentTimeLocale->x) */ /* * We do not implement alternate representations. However, we always * check whether a given modifier is allowed for a certain conversion. */ #define _ALT_E 0x01 #define _ALT_O 0x02 #define _LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); } static int _conv_num(const unsigned char **, int *, int, int); static char *_strptime(const char *, const char *, struct tm *, int); char * strptime(const char *buf, const char *fmt, struct tm *tm) { return(_strptime(buf, fmt, tm, 1)); } static char * _strptime(const char *buf, const char *fmt, struct tm *tm, int initialize) { unsigned char c; const unsigned char *bp; size_t len; int alt_format, i; static int century, relyear; if (initialize) { century = TM_YEAR_BASE; relyear = -1; } bp = (unsigned char *)buf; while ((c = *fmt) != '\0') { /* Clear `alternate' modifier prior to new conversion. */ alt_format = 0; /* Eat up white-space. */ if (isspace(c)) { while (isspace(*bp)) bp++; fmt++; continue; } if ((c = *fmt++) != '%') goto literal; again: switch (c = *fmt++) { case '%': /* "%%" is converted to "%". */ literal: if (c != *bp++) return (NULL); break; /* * "Alternative" modifiers. Just set the appropriate flag * and start over again. */ case 'E': /* "%E?" alternative conversion modifier. */ _LEGAL_ALT(0); alt_format |= _ALT_E; goto again; case 'O': /* "%O?" alternative conversion modifier. */ _LEGAL_ALT(0); alt_format |= _ALT_O; goto again; /* * "Complex" conversion rules, implemented through recursion. */ #if 0 case 'c': /* Date and time, using the locale's format. */ _LEGAL_ALT(_ALT_E); if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0))) return (NULL); break; #endif case 'D': /* The date as "%m/%d/%y". */ _LEGAL_ALT(0); if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0))) return (NULL); break; case 'R': /* The time as "%H:%M". */ _LEGAL_ALT(0); if (!(bp = _strptime(bp, "%H:%M", tm, 0))) return (NULL); break; case 'r': /* The time as "%I:%M:%S %p". */ _LEGAL_ALT(0); if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0))) return (NULL); break; case 'T': /* The time as "%H:%M:%S". */ _LEGAL_ALT(0); if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0))) return (NULL); break; #if 0 case 'X': /* The time, using the locale's format. */ _LEGAL_ALT(_ALT_E); if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0))) return (NULL); break; case 'x': /* The date, using the locale's format. */ _LEGAL_ALT(_ALT_E); if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0))) return (NULL); break; #endif /* * "Elementary" conversion rules. */ #if 0 case 'A': /* The day of week, using the locale's form. */ case 'a': _LEGAL_ALT(0); for (i = 0; i < 7; i++) { /* Full name. */ len = strlen(_ctloc(day[i])); if (strncasecmp(_ctloc(day[i]), bp, len) == 0) break; /* Abbreviated name. */ len = strlen(_ctloc(abday[i])); if (strncasecmp(_ctloc(abday[i]), bp, len) == 0) break; } /* Nothing matched. */ if (i == 7) return (NULL); tm->tm_wday = i; bp += len; break; case 'B': /* The month, using the locale's form. */ case 'b': case 'h': _LEGAL_ALT(0); for (i = 0; i < 12; i++) { /* Full name. */ len = strlen(_ctloc(mon[i])); if (strncasecmp(_ctloc(mon[i]), bp, len) == 0) break; /* Abbreviated name. */ len = strlen(_ctloc(abmon[i])); if (strncasecmp(_ctloc(abmon[i]), bp, len) == 0) break; } /* Nothing matched. */ if (i == 12) return (NULL); tm->tm_mon = i; bp += len; break; #endif case 'C': /* The century number. */ _LEGAL_ALT(_ALT_E); if (!(_conv_num(&bp, &i, 0, 99))) return (NULL); century = i * 100; break; case 'd': /* The day of month. */ case 'e': _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_mday, 1, 31))) return (NULL); break; case 'k': /* The hour (24-hour clock representation). */ _LEGAL_ALT(0); /* FALLTHROUGH */ case 'H': _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_hour, 0, 23))) return (NULL); break; case 'l': /* The hour (12-hour clock representation). */ _LEGAL_ALT(0); /* FALLTHROUGH */ case 'I': _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_hour, 1, 12))) return (NULL); break; case 'j': /* The day of year. */ _LEGAL_ALT(0); if (!(_conv_num(&bp, &tm->tm_yday, 1, 366))) return (NULL); tm->tm_yday--; break; case 'M': /* The minute. */ _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_min, 0, 59))) return (NULL); break; case 'm': /* The month. */ _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_mon, 1, 12))) return (NULL); tm->tm_mon--; break; #if 0 case 'p': /* The locale's equivalent of AM/PM. */ _LEGAL_ALT(0); /* AM? */ len = strlen(_ctloc(am_pm[0])); if (strncasecmp(_ctloc(am_pm[0]), bp, len) == 0) { if (tm->tm_hour > 12) /* i.e., 13:00 AM ?! */ return (NULL); else if (tm->tm_hour == 12) tm->tm_hour = 0; bp += len; break; } /* PM? */ len = strlen(_ctloc(am_pm[1])); if (strncasecmp(_ctloc(am_pm[1]), bp, len) == 0) { if (tm->tm_hour > 12) /* i.e., 13:00 PM ?! */ return (NULL); else if (tm->tm_hour < 12) tm->tm_hour += 12; bp += len; break; } /* Nothing matched. */ return (NULL); #endif case 'S': /* The seconds. */ _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_sec, 0, 61))) return (NULL); break; case 'U': /* The week of year, beginning on sunday. */ case 'W': /* The week of year, beginning on monday. */ _LEGAL_ALT(_ALT_O); /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ if (!(_conv_num(&bp, &i, 0, 53))) return (NULL); break; case 'w': /* The day of week, beginning on sunday. */ _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_wday, 0, 6))) return (NULL); break; case 'Y': /* The year. */ _LEGAL_ALT(_ALT_E); if (!(_conv_num(&bp, &i, 0, 9999))) return (NULL); relyear = -1; tm->tm_year = i - TM_YEAR_BASE; break; case 'y': /* The year within the century (2 digits). */ _LEGAL_ALT(_ALT_E | _ALT_O); if (!(_conv_num(&bp, &relyear, 0, 99))) return (NULL); break; /* * Miscellaneous conversions. */ case 'n': /* Any kind of white-space. */ case 't': _LEGAL_ALT(0); while (isspace(*bp)) bp++; break; default: /* Unknown/unsupported conversion. */ return (NULL); } } /* * We need to evaluate the two digit year spec (%y) * last as we can get a century spec (%C) at any time. */ if (relyear != -1) { if (century == TM_YEAR_BASE) { if (relyear <= 68) tm->tm_year = relyear + 2000 - TM_YEAR_BASE; else tm->tm_year = relyear + 1900 - TM_YEAR_BASE; } else { tm->tm_year = relyear + century - TM_YEAR_BASE; } } return ((char *)bp); } static int _conv_num(const unsigned char **buf, int *dest, int llim, int ulim) { int result = 0; int rulim = ulim; if (**buf < '0' || **buf > '9') return (0); /* we use rulim to break out of the loop when we run out of digits */ do { result *= 10; result += *(*buf)++ - '0'; rulim /= 10; } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); if (result < llim || result > ulim) return (0); *dest = result; return (1); } #endif /* HAVE_STRPTIME */ openssh-7.2p2/openbsd-compat/strsep.c010064400017500001750000000051351267006270000160550ustar00djmdjm/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ /*- * Copyright (c) 1990, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/string/strsep.c */ #include "includes.h" #if !defined(HAVE_STRSEP) #include #include /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * strsep(char **stringp, const char *delim) { char *s; const char *spanp; int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } #endif /* !defined(HAVE_STRSEP) */ openssh-7.2p2/openbsd-compat/strtoll.c010064400017500001750000000104461267006270000162410ustar00djmdjm/* $OpenBSD: strtoll.c,v 1.6 2005/11/10 10:00:17 espie Exp $ */ /*- * Copyright (c) 1992 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/strtoll.c */ #include "includes.h" #ifndef HAVE_STRTOLL #include #include #include #include #include /* * Convert a string to a long long. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long long strtoll(const char *nptr, char **endptr, int base) { const char *s; long long acc, cutoff; int c; int neg, any, cutlim; /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = (unsigned char) *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for long longs is * [-9223372036854775808..9223372036854775807] and the input base * is 10, cutoff will be set to 922337203685477580 and cutlim to * either 7 (neg==0) or 8 (neg==1), meaning that if we have * accumulated a value > 922337203685477580, or equal but the * next digit is > 7 (or 8), the number is too big, and we will * return a range error. * * Set any if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? LLONG_MIN : LLONG_MAX; cutlim = cutoff % base; cutoff /= base; if (neg) { if (cutlim > 0) { cutlim -= base; cutoff += 1; } cutlim = -cutlim; } for (acc = 0, any = 0;; c = (unsigned char) *s++) { if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0) continue; if (neg) { if (acc < cutoff || (acc == cutoff && c > cutlim)) { any = -1; acc = LLONG_MIN; errno = ERANGE; } else { any = 1; acc *= base; acc -= c; } } else { if (acc > cutoff || (acc == cutoff && c > cutlim)) { any = -1; acc = LLONG_MAX; errno = ERANGE; } else { any = 1; acc *= base; acc += c; } } } if (endptr != 0) *endptr = (char *) (any ? s - 1 : nptr); return (acc); } #endif /* HAVE_STRTOLL */ openssh-7.2p2/openbsd-compat/strtonum.c010064400017500001750000000035461267006270000164340ustar00djmdjm/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ /* * Copyright (c) 2004 Ted Unangst and Todd Miller * All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */ #include "includes.h" #ifndef HAVE_STRTONUM #include #include #include #define INVALID 1 #define TOOSMALL 2 #define TOOLARGE 3 long long strtonum(const char *numstr, long long minval, long long maxval, const char **errstrp) { long long ll = 0; char *ep; int error = 0; struct errval { const char *errstr; int err; } ev[4] = { { NULL, 0 }, { "invalid", EINVAL }, { "too small", ERANGE }, { "too large", ERANGE }, }; ev[0].err = errno; errno = 0; if (minval > maxval) error = INVALID; else { ll = strtoll(numstr, &ep, 10); if (numstr == ep || *ep != '\0') error = INVALID; else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) error = TOOSMALL; else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) error = TOOLARGE; } if (errstrp != NULL) *errstrp = ev[error].errstr; errno = ev[error].err; if (error) ll = 0; return (ll); } #endif /* HAVE_STRTONUM */ openssh-7.2p2/openbsd-compat/strtoul.c010064400017500001750000000061071267006270000162510ustar00djmdjm/* $OpenBSD: strtoul.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1990 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/strtoul.c */ #include "includes.h" #ifndef HAVE_STRTOUL #include #include #include #include /* * Convert a string to an unsigned long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long strtoul(const char *nptr, char **endptr, int base) { const char *s; unsigned long acc, cutoff; int c; int neg, any, cutlim; /* * See strtol for comments as to the logic used. */ s = nptr; do { c = (unsigned char) *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; cutoff = ULONG_MAX / (unsigned long)base; cutlim = ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = (unsigned char) *s++) { if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0) continue; if (acc > cutoff || acc == cutoff && c > cutlim) { any = -1; acc = ULONG_MAX; errno = ERANGE; } else { any = 1; acc *= (unsigned long)base; acc += c; } } if (neg && any > 0) acc = -acc; if (endptr != 0) *endptr = (char *) (any ? s - 1 : nptr); return (acc); } #endif /* !HAVE_STRTOUL */ openssh-7.2p2/openbsd-compat/strtoull.c010064400017500001750000000062051267006270000164240ustar00djmdjm/* $OpenBSD: strtoull.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */ /*- * Copyright (c) 1992 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. */ /* OPENBSD ORIGINAL: lib/libc/stdlib/strtoull.c */ #include "includes.h" #ifndef HAVE_STRTOULL #include #include #include #include #include /* * Convert a string to an unsigned long long. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long long strtoull(const char *nptr, char **endptr, int base) { const char *s; unsigned long long acc, cutoff; int c; int neg, any, cutlim; /* * See strtoq for comments as to the logic used. */ s = nptr; do { c = (unsigned char) *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; cutoff = ULLONG_MAX / (unsigned long long)base; cutlim = ULLONG_MAX % (unsigned long long)base; for (acc = 0, any = 0;; c = (unsigned char) *s++) { if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0) continue; if (acc > cutoff || (acc == cutoff && c > cutlim)) { any = -1; acc = ULLONG_MAX; errno = ERANGE; } else { any = 1; acc *= (unsigned long long)base; acc += c; } } if (neg && any > 0) acc = -acc; if (endptr != 0) *endptr = (char *) (any ? s - 1 : nptr); return (acc); } #endif /* !HAVE_STRTOULL */ openssh-7.2p2/openbsd-compat/sys-queue.h010064400017500001750000000516361267006270000165110ustar00djmdjm/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* * Copyright (c) 1991, 1993 * 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. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ /* OPENBSD ORIGINAL: sys/sys/queue.h */ #ifndef _FAKE_QUEUE_H_ #define _FAKE_QUEUE_H_ /* * Require for OS/X and other platforms that have old/broken/incomplete * . */ #undef SLIST_HEAD #undef SLIST_HEAD_INITIALIZER #undef SLIST_ENTRY #undef SLIST_FOREACH_PREVPTR #undef SLIST_FIRST #undef SLIST_END #undef SLIST_EMPTY #undef SLIST_NEXT #undef SLIST_FOREACH #undef SLIST_INIT #undef SLIST_INSERT_AFTER #undef SLIST_INSERT_HEAD #undef SLIST_REMOVE_HEAD #undef SLIST_REMOVE #undef SLIST_REMOVE_NEXT #undef LIST_HEAD #undef LIST_HEAD_INITIALIZER #undef LIST_ENTRY #undef LIST_FIRST #undef LIST_END #undef LIST_EMPTY #undef LIST_NEXT #undef LIST_FOREACH #undef LIST_INIT #undef LIST_INSERT_AFTER #undef LIST_INSERT_BEFORE #undef LIST_INSERT_HEAD #undef LIST_REMOVE #undef LIST_REPLACE #undef SIMPLEQ_HEAD #undef SIMPLEQ_HEAD_INITIALIZER #undef SIMPLEQ_ENTRY #undef SIMPLEQ_FIRST #undef SIMPLEQ_END #undef SIMPLEQ_EMPTY #undef SIMPLEQ_NEXT #undef SIMPLEQ_FOREACH #undef SIMPLEQ_INIT #undef SIMPLEQ_INSERT_HEAD #undef SIMPLEQ_INSERT_TAIL #undef SIMPLEQ_INSERT_AFTER #undef SIMPLEQ_REMOVE_HEAD #undef TAILQ_HEAD #undef TAILQ_HEAD_INITIALIZER #undef TAILQ_ENTRY #undef TAILQ_FIRST #undef TAILQ_END #undef TAILQ_NEXT #undef TAILQ_LAST #undef TAILQ_PREV #undef TAILQ_EMPTY #undef TAILQ_FOREACH #undef TAILQ_FOREACH_REVERSE #undef TAILQ_INIT #undef TAILQ_INSERT_HEAD #undef TAILQ_INSERT_TAIL #undef TAILQ_INSERT_AFTER #undef TAILQ_INSERT_BEFORE #undef TAILQ_REMOVE #undef TAILQ_REPLACE #undef CIRCLEQ_HEAD #undef CIRCLEQ_HEAD_INITIALIZER #undef CIRCLEQ_ENTRY #undef CIRCLEQ_FIRST #undef CIRCLEQ_LAST #undef CIRCLEQ_END #undef CIRCLEQ_NEXT #undef CIRCLEQ_PREV #undef CIRCLEQ_EMPTY #undef CIRCLEQ_FOREACH #undef CIRCLEQ_FOREACH_REVERSE #undef CIRCLEQ_INIT #undef CIRCLEQ_INSERT_AFTER #undef CIRCLEQ_INSERT_BEFORE #undef CIRCLEQ_INSERT_HEAD #undef CIRCLEQ_INSERT_TAIL #undef CIRCLEQ_REMOVE #undef CIRCLEQ_REPLACE /* * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues, and circular queues. * * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at * the expense of O(n) removal for arbitrary elements. New elements can be * added to the list after an existing element or at the head of the list. * Elements being removed from the head of the list should use the explicit * macro for this purpose for optimum efficiency. A singly-linked list may * only be traversed in the forward direction. Singly-linked lists are ideal * for applications with large datasets and few or no removals or for * implementing a LIFO queue. * * A list is headed by a single forward pointer (or an array of forward * pointers for a hash table header). The elements are doubly linked * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list * may only be traversed in the forward direction. * * A simple queue is headed by a pair of pointers, one the head of the * list and the other to the tail of the list. The elements are singly * linked to save space, so elements can only be removed from the * head of the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the * list. A simple queue may only be traversed in the forward direction. * * A tail queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * * A circle queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the list. * A circle queue may be traversed in either direction, but has a more * complex end of list detection. * * For details on the use of these macros, see the queue(3) manual page. */ #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) #define _Q_INVALIDATE(a) (a) = ((void *)-1) #else #define _Q_INVALIDATE(a) #endif /* * Singly-linked List definitions. */ #define SLIST_HEAD(name, type) \ struct name { \ struct type *slh_first; /* first element */ \ } #define SLIST_HEAD_INITIALIZER(head) \ { NULL } #define SLIST_ENTRY(type) \ struct { \ struct type *sle_next; /* next element */ \ } /* * Singly-linked List access methods. */ #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_END(head) NULL #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_FOREACH(var, head, field) \ for((var) = SLIST_FIRST(head); \ (var) != SLIST_END(head); \ (var) = SLIST_NEXT(var, field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST(head); \ (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ (var) = (tvar)) /* * Singly-linked List functions. */ #define SLIST_INIT(head) { \ SLIST_FIRST(head) = SLIST_END(head); \ } #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ (elm)->field.sle_next = (slistelm)->field.sle_next; \ (slistelm)->field.sle_next = (elm); \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ (elm)->field.sle_next = (head)->slh_first; \ (head)->slh_first = (elm); \ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ (head)->slh_first = (head)->slh_first->field.sle_next; \ } while (0) #define SLIST_REMOVE(head, elm, type, field) do { \ if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } else { \ struct type *curelm = (head)->slh_first; \ \ while (curelm->field.sle_next != (elm)) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = \ curelm->field.sle_next->field.sle_next; \ _Q_INVALIDATE((elm)->field.sle_next); \ } \ } while (0) /* * List definitions. */ #define LIST_HEAD(name, type) \ struct name { \ struct type *lh_first; /* first element */ \ } #define LIST_HEAD_INITIALIZER(head) \ { NULL } #define LIST_ENTRY(type) \ struct { \ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } /* * List access methods */ #define LIST_FIRST(head) ((head)->lh_first) #define LIST_END(head) NULL #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) #define LIST_NEXT(elm, field) ((elm)->field.le_next) #define LIST_FOREACH(var, head, field) \ for((var) = LIST_FIRST(head); \ (var)!= LIST_END(head); \ (var) = LIST_NEXT(var, field)) #define LIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = LIST_FIRST(head); \ (var) && ((tvar) = LIST_NEXT(var, field), 1); \ (var) = (tvar)) /* * List functions. */ #define LIST_INIT(head) do { \ LIST_FIRST(head) = LIST_END(head); \ } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ (listelm)->field.le_next->field.le_prev = \ &(elm)->field.le_next; \ (listelm)->field.le_next = (elm); \ (elm)->field.le_prev = &(listelm)->field.le_next; \ } while (0) #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ (elm)->field.le_prev = (listelm)->field.le_prev; \ (elm)->field.le_next = (listelm); \ *(listelm)->field.le_prev = (elm); \ (listelm)->field.le_prev = &(elm)->field.le_next; \ } while (0) #define LIST_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.le_next = (head)->lh_first) != NULL) \ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ (head)->lh_first = (elm); \ (elm)->field.le_prev = &(head)->lh_first; \ } while (0) #define LIST_REMOVE(elm, field) do { \ if ((elm)->field.le_next != NULL) \ (elm)->field.le_next->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = (elm)->field.le_next; \ _Q_INVALIDATE((elm)->field.le_prev); \ _Q_INVALIDATE((elm)->field.le_next); \ } while (0) #define LIST_REPLACE(elm, elm2, field) do { \ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ (elm2)->field.le_next->field.le_prev = \ &(elm2)->field.le_next; \ (elm2)->field.le_prev = (elm)->field.le_prev; \ *(elm2)->field.le_prev = (elm2); \ _Q_INVALIDATE((elm)->field.le_prev); \ _Q_INVALIDATE((elm)->field.le_next); \ } while (0) /* * Simple queue definitions. */ #define SIMPLEQ_HEAD(name, type) \ struct name { \ struct type *sqh_first; /* first element */ \ struct type **sqh_last; /* addr of last next element */ \ } #define SIMPLEQ_HEAD_INITIALIZER(head) \ { NULL, &(head).sqh_first } #define SIMPLEQ_ENTRY(type) \ struct { \ struct type *sqe_next; /* next element */ \ } /* * Simple queue access methods. */ #define SIMPLEQ_FIRST(head) ((head)->sqh_first) #define SIMPLEQ_END(head) NULL #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) #define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) #define SIMPLEQ_FOREACH(var, head, field) \ for((var) = SIMPLEQ_FIRST(head); \ (var) != SIMPLEQ_END(head); \ (var) = SIMPLEQ_NEXT(var, field)) #define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SIMPLEQ_FIRST(head); \ (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ (var) = (tvar)) /* * Simple queue functions. */ #define SIMPLEQ_INIT(head) do { \ (head)->sqh_first = NULL; \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) #define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ (head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_first = (elm); \ } while (0) #define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.sqe_next = NULL; \ *(head)->sqh_last = (elm); \ (head)->sqh_last = &(elm)->field.sqe_next; \ } while (0) #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ (head)->sqh_last = &(elm)->field.sqe_next; \ (listelm)->field.sqe_next = (elm); \ } while (0) #define SIMPLEQ_REMOVE_HEAD(head, field) do { \ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ == NULL) \ (head)->sqh_last = &(elm)->field.sqe_next; \ } while (0) /* * Tail queue definitions. */ #define TAILQ_HEAD(name, type) \ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ } #define TAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).tqh_first } #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ } /* * tail queue access methods */ #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_END(head) NULL #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_LAST(head, headname) \ (*(((struct headname *)((head)->tqh_last))->tqh_last)) /* XXX */ #define TAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_EMPTY(head) \ (TAILQ_FIRST(head) == TAILQ_END(head)) #define TAILQ_FOREACH(var, head, field) \ for((var) = TAILQ_FIRST(head); \ (var) != TAILQ_END(head); \ (var) = TAILQ_NEXT(var, field)) #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = TAILQ_FIRST(head); \ (var) != TAILQ_END(head) && \ ((tvar) = TAILQ_NEXT(var, field), 1); \ (var) = (tvar)) #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for((var) = TAILQ_LAST(head, headname); \ (var) != TAILQ_END(head); \ (var) = TAILQ_PREV(var, headname, field)) #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ for ((var) = TAILQ_LAST(head, headname); \ (var) != TAILQ_END(head) && \ ((tvar) = TAILQ_PREV(var, headname, field), 1); \ (var) = (tvar)) /* * Tail queue functions. */ #define TAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ (head)->tqh_last = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ (head)->tqh_first->field.tqe_prev = \ &(elm)->field.tqe_next; \ else \ (head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_first = (elm); \ (elm)->field.tqe_prev = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.tqe_next = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &(elm)->field.tqe_next; \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ (elm)->field.tqe_next->field.tqe_prev = \ &(elm)->field.tqe_next; \ else \ (head)->tqh_last = &(elm)->field.tqe_next; \ (listelm)->field.tqe_next = (elm); \ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ (elm)->field.tqe_next = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ } while (0) #define TAILQ_REMOVE(head, elm, field) do { \ if (((elm)->field.tqe_next) != NULL) \ (elm)->field.tqe_next->field.tqe_prev = \ (elm)->field.tqe_prev; \ else \ (head)->tqh_last = (elm)->field.tqe_prev; \ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ _Q_INVALIDATE((elm)->field.tqe_prev); \ _Q_INVALIDATE((elm)->field.tqe_next); \ } while (0) #define TAILQ_REPLACE(head, elm, elm2, field) do { \ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ (elm2)->field.tqe_next->field.tqe_prev = \ &(elm2)->field.tqe_next; \ else \ (head)->tqh_last = &(elm2)->field.tqe_next; \ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ *(elm2)->field.tqe_prev = (elm2); \ _Q_INVALIDATE((elm)->field.tqe_prev); \ _Q_INVALIDATE((elm)->field.tqe_next); \ } while (0) /* * Circular queue definitions. */ #define CIRCLEQ_HEAD(name, type) \ struct name { \ struct type *cqh_first; /* first element */ \ struct type *cqh_last; /* last element */ \ } #define CIRCLEQ_HEAD_INITIALIZER(head) \ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } #define CIRCLEQ_ENTRY(type) \ struct { \ struct type *cqe_next; /* next element */ \ struct type *cqe_prev; /* previous element */ \ } /* * Circular queue access methods */ #define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_LAST(head) ((head)->cqh_last) #define CIRCLEQ_END(head) ((void *)(head)) #define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) #define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) #define CIRCLEQ_EMPTY(head) \ (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) #define CIRCLEQ_FOREACH(var, head, field) \ for((var) = CIRCLEQ_FIRST(head); \ (var) != CIRCLEQ_END(head); \ (var) = CIRCLEQ_NEXT(var, field)) #define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = CIRCLEQ_FIRST(head); \ (var) != CIRCLEQ_END(head) && \ ((tvar) = CIRCLEQ_NEXT(var, field), 1); \ (var) = (tvar)) #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ for((var) = CIRCLEQ_LAST(head); \ (var) != CIRCLEQ_END(head); \ (var) = CIRCLEQ_PREV(var, field)) #define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ for ((var) = CIRCLEQ_LAST(head, headname); \ (var) != CIRCLEQ_END(head) && \ ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \ (var) = (tvar)) /* * Circular queue functions. */ #define CIRCLEQ_INIT(head) do { \ (head)->cqh_first = CIRCLEQ_END(head); \ (head)->cqh_last = CIRCLEQ_END(head); \ } while (0) #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ (elm)->field.cqe_prev = (listelm); \ if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ (head)->cqh_last = (elm); \ else \ (listelm)->field.cqe_next->field.cqe_prev = (elm); \ (listelm)->field.cqe_next = (elm); \ } while (0) #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ (elm)->field.cqe_next = (listelm); \ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ (head)->cqh_first = (elm); \ else \ (listelm)->field.cqe_prev->field.cqe_next = (elm); \ (listelm)->field.cqe_prev = (elm); \ } while (0) #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ (elm)->field.cqe_next = (head)->cqh_first; \ (elm)->field.cqe_prev = CIRCLEQ_END(head); \ if ((head)->cqh_last == CIRCLEQ_END(head)) \ (head)->cqh_last = (elm); \ else \ (head)->cqh_first->field.cqe_prev = (elm); \ (head)->cqh_first = (elm); \ } while (0) #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.cqe_next = CIRCLEQ_END(head); \ (elm)->field.cqe_prev = (head)->cqh_last; \ if ((head)->cqh_first == CIRCLEQ_END(head)) \ (head)->cqh_first = (elm); \ else \ (head)->cqh_last->field.cqe_next = (elm); \ (head)->cqh_last = (elm); \ } while (0) #define CIRCLEQ_REMOVE(head, elm, field) do { \ if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ (head)->cqh_last = (elm)->field.cqe_prev; \ else \ (elm)->field.cqe_next->field.cqe_prev = \ (elm)->field.cqe_prev; \ if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ (head)->cqh_first = (elm)->field.cqe_next; \ else \ (elm)->field.cqe_prev->field.cqe_next = \ (elm)->field.cqe_next; \ _Q_INVALIDATE((elm)->field.cqe_prev); \ _Q_INVALIDATE((elm)->field.cqe_next); \ } while (0) #define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ CIRCLEQ_END(head)) \ (head).cqh_last = (elm2); \ else \ (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ CIRCLEQ_END(head)) \ (head).cqh_first = (elm2); \ else \ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ _Q_INVALIDATE((elm)->field.cqe_prev); \ _Q_INVALIDATE((elm)->field.cqe_next); \ } while (0) #endif /* !_FAKE_QUEUE_H_ */ openssh-7.2p2/openbsd-compat/sys-tree.h010064400017500001750000000612651267006270000163230ustar00djmdjm/* $OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $ */ /* * Copyright 2002 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. */ /* OPENBSD ORIGINAL: sys/sys/tree.h */ #include "config.h" #ifdef NO_ATTRIBUTE_ON_RETURN_TYPE # define __attribute__(x) #endif #ifndef _SYS_TREE_H_ #define _SYS_TREE_H_ /* * This file defines data structures for different types of trees: * splay trees and red-black trees. * * A splay tree is a self-organizing data structure. Every operation * on the tree causes a splay to happen. The splay moves the requested * node to the root of the tree and partly rebalances it. * * This has the benefit that request locality causes faster lookups as * the requested nodes move to the top of the tree. On the other hand, * every lookup causes memory writes. * * The Balance Theorem bounds the total access time for m operations * and n inserts on an initially empty tree as O((m + n)lg n). The * amortized cost for a sequence of m accesses to a splay tree is O(lg n); * * A red-black tree is a binary search tree with the node color as an * extra attribute. It fulfills a set of conditions: * - every search path from the root to a leaf consists of the * same number of black nodes, * - each red node (except for the root) has a black parent, * - each leaf node is black. * * Every operation on a red-black tree is bounded as O(lg n). * The maximum height of a red-black tree is 2lg (n+1). */ #define SPLAY_HEAD(name, type) \ struct name { \ struct type *sph_root; /* root of the tree */ \ } #define SPLAY_INITIALIZER(root) \ { NULL } #define SPLAY_INIT(root) do { \ (root)->sph_root = NULL; \ } while (0) #define SPLAY_ENTRY(type) \ struct { \ struct type *spe_left; /* left element */ \ struct type *spe_right; /* right element */ \ } #define SPLAY_LEFT(elm, field) (elm)->field.spe_left #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right #define SPLAY_ROOT(head) (head)->sph_root #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (0) #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (0) #define SPLAY_LINKLEFT(head, tmp, field) do { \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ } while (0) #define SPLAY_LINKRIGHT(head, tmp, field) do { \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ } while (0) #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ } while (0) /* Generates prototypes and inline functions */ #define SPLAY_PROTOTYPE(name, type, field, cmp) \ void name##_SPLAY(struct name *, struct type *); \ void name##_SPLAY_MINMAX(struct name *, int); \ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ \ /* Finds the node with the same key as elm */ \ static __inline struct type * \ name##_SPLAY_FIND(struct name *head, struct type *elm) \ { \ if (SPLAY_EMPTY(head)) \ return(NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) \ return (head->sph_root); \ return (NULL); \ } \ \ static __inline struct type * \ name##_SPLAY_NEXT(struct name *head, struct type *elm) \ { \ name##_SPLAY(head, elm); \ if (SPLAY_RIGHT(elm, field) != NULL) { \ elm = SPLAY_RIGHT(elm, field); \ while (SPLAY_LEFT(elm, field) != NULL) { \ elm = SPLAY_LEFT(elm, field); \ } \ } else \ elm = NULL; \ return (elm); \ } \ \ static __inline struct type * \ name##_SPLAY_MIN_MAX(struct name *head, int val) \ { \ name##_SPLAY_MINMAX(head, val); \ return (SPLAY_ROOT(head)); \ } /* Main splay operation. * Moves node close to the key of elm to top */ #define SPLAY_GENERATE(name, type, field, cmp) \ struct type * \ name##_SPLAY_INSERT(struct name *head, struct type *elm) \ { \ if (SPLAY_EMPTY(head)) { \ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ } else { \ int __comp; \ name##_SPLAY(head, elm); \ __comp = (cmp)(elm, (head)->sph_root); \ if(__comp < 0) { \ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ SPLAY_RIGHT(elm, field) = (head)->sph_root; \ SPLAY_LEFT((head)->sph_root, field) = NULL; \ } else if (__comp > 0) { \ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ SPLAY_LEFT(elm, field) = (head)->sph_root; \ SPLAY_RIGHT((head)->sph_root, field) = NULL; \ } else \ return ((head)->sph_root); \ } \ (head)->sph_root = (elm); \ return (NULL); \ } \ \ struct type * \ name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ { \ struct type *__tmp; \ if (SPLAY_EMPTY(head)) \ return (NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) { \ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ } else { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ name##_SPLAY(head, elm); \ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ } \ return (elm); \ } \ return (NULL); \ } \ \ void \ name##_SPLAY(struct name *head, struct type *elm) \ { \ struct type __node, *__left, *__right, *__tmp; \ int __comp; \ \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while ((__comp = (cmp)(elm, (head)->sph_root))) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) < 0){ \ SPLAY_ROTATE_RIGHT(head, __tmp, field); \ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) > 0){ \ SPLAY_ROTATE_LEFT(head, __tmp, field); \ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } \ \ /* Splay with either the minimum or the maximum element \ * Used to find minimum or maximum element in tree. \ */ \ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ { \ struct type __node, *__left, *__right, *__tmp; \ \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while (1) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp < 0){ \ SPLAY_ROTATE_RIGHT(head, __tmp, field); \ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp > 0) { \ SPLAY_ROTATE_LEFT(head, __tmp, field); \ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } #define SPLAY_NEGINF -1 #define SPLAY_INF 1 #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) #define SPLAY_FOREACH(x, name, head) \ for ((x) = SPLAY_MIN(name, head); \ (x) != NULL; \ (x) = SPLAY_NEXT(name, head, x)) /* Macros that define a red-black tree */ #define RB_HEAD(name, type) \ struct name { \ struct type *rbh_root; /* root of the tree */ \ } #define RB_INITIALIZER(root) \ { NULL } #define RB_INIT(root) do { \ (root)->rbh_root = NULL; \ } while (0) #define RB_BLACK 0 #define RB_RED 1 #define RB_ENTRY(type) \ struct { \ struct type *rbe_left; /* left element */ \ struct type *rbe_right; /* right element */ \ struct type *rbe_parent; /* parent element */ \ int rbe_color; /* node color */ \ } #define RB_LEFT(elm, field) (elm)->field.rbe_left #define RB_RIGHT(elm, field) (elm)->field.rbe_right #define RB_PARENT(elm, field) (elm)->field.rbe_parent #define RB_COLOR(elm, field) (elm)->field.rbe_color #define RB_ROOT(head) (head)->rbh_root #define RB_EMPTY(head) (RB_ROOT(head) == NULL) #define RB_SET(elm, parent, field) do { \ RB_PARENT(elm, field) = parent; \ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ RB_COLOR(elm, field) = RB_RED; \ } while (0) #define RB_SET_BLACKRED(black, red, field) do { \ RB_COLOR(black, field) = RB_BLACK; \ RB_COLOR(red, field) = RB_RED; \ } while (0) #ifndef RB_AUGMENT #define RB_AUGMENT(x) do {} while (0) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ (tmp) = RB_RIGHT(elm, field); \ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ } else \ (head)->rbh_root = (tmp); \ RB_LEFT(tmp, field) = (elm); \ RB_PARENT(elm, field) = (tmp); \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ } while (0) #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ (tmp) = RB_LEFT(elm, field); \ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ } else \ (head)->rbh_root = (tmp); \ RB_RIGHT(tmp, field) = (elm); \ RB_PARENT(elm, field) = (tmp); \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ } while (0) /* Generates prototypes and inline functions */ #define RB_PROTOTYPE(name, type, field, cmp) \ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ attr struct type *name##_RB_INSERT(struct name *, struct type *); \ attr struct type *name##_RB_FIND(struct name *, struct type *); \ attr struct type *name##_RB_NFIND(struct name *, struct type *); \ attr struct type *name##_RB_NEXT(struct type *); \ attr struct type *name##_RB_PREV(struct type *); \ attr struct type *name##_RB_MINMAX(struct name *, int); \ \ /* Main rb operation. * Moves node close to the key of elm to top */ #define RB_GENERATE(name, type, field, cmp) \ RB_GENERATE_INTERNAL(name, type, field, cmp,) #define RB_GENERATE_STATIC(name, type, field, cmp) \ RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ attr void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ while ((parent = RB_PARENT(elm, field)) && \ RB_COLOR(parent, field) == RB_RED) { \ gparent = RB_PARENT(parent, field); \ if (parent == RB_LEFT(gparent, field)) { \ tmp = RB_RIGHT(gparent, field); \ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ RB_COLOR(tmp, field) = RB_BLACK; \ RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ if (RB_RIGHT(parent, field) == elm) { \ RB_ROTATE_LEFT(head, parent, tmp, field);\ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ RB_SET_BLACKRED(parent, gparent, field); \ RB_ROTATE_RIGHT(head, gparent, tmp, field); \ } else { \ tmp = RB_LEFT(gparent, field); \ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ RB_COLOR(tmp, field) = RB_BLACK; \ RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ if (RB_LEFT(parent, field) == elm) { \ RB_ROTATE_RIGHT(head, parent, tmp, field);\ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ RB_SET_BLACKRED(parent, gparent, field); \ RB_ROTATE_LEFT(head, gparent, tmp, field); \ } \ } \ RB_COLOR(head->rbh_root, field) = RB_BLACK; \ } \ \ attr void \ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ { \ struct type *tmp; \ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ elm != RB_ROOT(head)) { \ if (RB_LEFT(parent, field) == elm) { \ tmp = RB_RIGHT(parent, field); \ if (RB_COLOR(tmp, field) == RB_RED) { \ RB_SET_BLACKRED(tmp, parent, field); \ RB_ROTATE_LEFT(head, parent, tmp, field);\ tmp = RB_RIGHT(parent, field); \ } \ if ((RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ RB_COLOR(tmp, field) = RB_RED; \ elm = parent; \ parent = RB_PARENT(elm, field); \ } else { \ if (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ struct type *oleft; \ if ((oleft = RB_LEFT(tmp, field)))\ RB_COLOR(oleft, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_RIGHT(head, tmp, oleft, field);\ tmp = RB_RIGHT(parent, field); \ } \ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ RB_COLOR(parent, field) = RB_BLACK; \ if (RB_RIGHT(tmp, field)) \ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ RB_ROTATE_LEFT(head, parent, tmp, field);\ elm = RB_ROOT(head); \ break; \ } \ } else { \ tmp = RB_LEFT(parent, field); \ if (RB_COLOR(tmp, field) == RB_RED) { \ RB_SET_BLACKRED(tmp, parent, field); \ RB_ROTATE_RIGHT(head, parent, tmp, field);\ tmp = RB_LEFT(parent, field); \ } \ if ((RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ RB_COLOR(tmp, field) = RB_RED; \ elm = parent; \ parent = RB_PARENT(elm, field); \ } else { \ if (RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ struct type *oright; \ if ((oright = RB_RIGHT(tmp, field)))\ RB_COLOR(oright, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_LEFT(head, tmp, oright, field);\ tmp = RB_LEFT(parent, field); \ } \ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ RB_COLOR(parent, field) = RB_BLACK; \ if (RB_LEFT(tmp, field)) \ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ RB_ROTATE_RIGHT(head, parent, tmp, field);\ elm = RB_ROOT(head); \ break; \ } \ } \ } \ if (elm) \ RB_COLOR(elm, field) = RB_BLACK; \ } \ \ attr struct type * \ name##_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *parent, *old = elm; \ int color; \ if (RB_LEFT(elm, field) == NULL) \ child = RB_RIGHT(elm, field); \ else if (RB_RIGHT(elm, field) == NULL) \ child = RB_LEFT(elm, field); \ else { \ struct type *left; \ elm = RB_RIGHT(elm, field); \ while ((left = RB_LEFT(elm, field))) \ elm = left; \ child = RB_RIGHT(elm, field); \ parent = RB_PARENT(elm, field); \ color = RB_COLOR(elm, field); \ if (child) \ RB_PARENT(child, field) = parent; \ if (parent) { \ if (RB_LEFT(parent, field) == elm) \ RB_LEFT(parent, field) = child; \ else \ RB_RIGHT(parent, field) = child; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = child; \ if (RB_PARENT(elm, field) == old) \ parent = elm; \ (elm)->field = (old)->field; \ if (RB_PARENT(old, field)) { \ if (RB_LEFT(RB_PARENT(old, field), field) == old)\ RB_LEFT(RB_PARENT(old, field), field) = elm;\ else \ RB_RIGHT(RB_PARENT(old, field), field) = elm;\ RB_AUGMENT(RB_PARENT(old, field)); \ } else \ RB_ROOT(head) = elm; \ RB_PARENT(RB_LEFT(old, field), field) = elm; \ if (RB_RIGHT(old, field)) \ RB_PARENT(RB_RIGHT(old, field), field) = elm; \ if (parent) { \ left = parent; \ do { \ RB_AUGMENT(left); \ } while ((left = RB_PARENT(left, field))); \ } \ goto color; \ } \ parent = RB_PARENT(elm, field); \ color = RB_COLOR(elm, field); \ if (child) \ RB_PARENT(child, field) = parent; \ if (parent) { \ if (RB_LEFT(parent, field) == elm) \ RB_LEFT(parent, field) = child; \ else \ RB_RIGHT(parent, field) = child; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = child; \ color: \ if (color == RB_BLACK) \ name##_RB_REMOVE_COLOR(head, parent, child); \ return (old); \ } \ \ /* Inserts a node into the RB tree */ \ attr struct type * \ name##_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ struct type *parent = NULL; \ int comp = 0; \ tmp = RB_ROOT(head); \ while (tmp) { \ parent = tmp; \ comp = (cmp)(elm, parent); \ if (comp < 0) \ tmp = RB_LEFT(tmp, field); \ else if (comp > 0) \ tmp = RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ RB_SET(elm, parent, field); \ if (parent != NULL) { \ if (comp < 0) \ RB_LEFT(parent, field) = elm; \ else \ RB_RIGHT(parent, field) = elm; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = elm; \ name##_RB_INSERT_COLOR(head, elm); \ return (NULL); \ } \ \ /* Finds the node with the same key as elm */ \ attr struct type * \ name##_RB_FIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ int comp; \ while (tmp) { \ comp = cmp(elm, tmp); \ if (comp < 0) \ tmp = RB_LEFT(tmp, field); \ else if (comp > 0) \ tmp = RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ return (NULL); \ } \ \ /* Finds the first node greater than or equal to the search key */ \ attr struct type * \ name##_RB_NFIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ struct type *res = NULL; \ int comp; \ while (tmp) { \ comp = cmp(elm, tmp); \ if (comp < 0) { \ res = tmp; \ tmp = RB_LEFT(tmp, field); \ } \ else if (comp > 0) \ tmp = RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ return (res); \ } \ \ /* ARGSUSED */ \ attr struct type * \ name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ elm = RB_RIGHT(elm, field); \ while (RB_LEFT(elm, field)) \ elm = RB_LEFT(elm, field); \ } else { \ if (RB_PARENT(elm, field) && \ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ elm = RB_PARENT(elm, field); \ else { \ while (RB_PARENT(elm, field) && \ (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ elm = RB_PARENT(elm, field); \ elm = RB_PARENT(elm, field); \ } \ } \ return (elm); \ } \ \ /* ARGSUSED */ \ attr struct type * \ name##_RB_PREV(struct type *elm) \ { \ if (RB_LEFT(elm, field)) { \ elm = RB_LEFT(elm, field); \ while (RB_RIGHT(elm, field)) \ elm = RB_RIGHT(elm, field); \ } else { \ if (RB_PARENT(elm, field) && \ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ elm = RB_PARENT(elm, field); \ else { \ while (RB_PARENT(elm, field) && \ (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ elm = RB_PARENT(elm, field); \ elm = RB_PARENT(elm, field); \ } \ } \ return (elm); \ } \ \ attr struct type * \ name##_RB_MINMAX(struct name *head, int val) \ { \ struct type *tmp = RB_ROOT(head); \ struct type *parent = NULL; \ while (tmp) { \ parent = tmp; \ if (val < 0) \ tmp = RB_LEFT(tmp, field); \ else \ tmp = RB_RIGHT(tmp, field); \ } \ return (parent); \ } #define RB_NEGINF -1 #define RB_INF 1 #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) #define RB_NEXT(name, x, y) name##_RB_NEXT(y) #define RB_PREV(name, x, y) name##_RB_PREV(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) #define RB_FOREACH(x, name, head) \ for ((x) = RB_MIN(name, head); \ (x) != NULL; \ (x) = name##_RB_NEXT(x)) #define RB_FOREACH_SAFE(x, name, head, y) \ for ((x) = RB_MIN(name, head); \ ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ (x) = (y)) #define RB_FOREACH_REVERSE(x, name, head) \ for ((x) = RB_MAX(name, head); \ (x) != NULL; \ (x) = name##_RB_PREV(x)) #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ for ((x) = RB_MAX(name, head); \ ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ (x) = (y)) #endif /* _SYS_TREE_H_ */ openssh-7.2p2/openbsd-compat/timingsafe_bcmp.c010064400017500001750000000022551267006270000176640ustar00djmdjm/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */ /* * Copyright (c) 2010 Damien Miller. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/string/timingsafe_bcmp.c */ #include "includes.h" #ifndef HAVE_TIMINGSAFE_BCMP int timingsafe_bcmp(const void *b1, const void *b2, size_t n) { const unsigned char *p1 = b1, *p2 = b2; int ret = 0; for (; n > 0; n--) ret |= *p1++ ^ *p2++; return (ret != 0); } #endif /* TIMINGSAFE_BCMP */ openssh-7.2p2/openbsd-compat/vis.c010064400017500001750000000126431267006270000153400ustar00djmdjm/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */ /*- * Copyright (c) 1989, 1993 * 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. */ /* OPENBSD ORIGINAL: lib/libc/gen/vis.c */ #include "includes.h" #if !defined(HAVE_STRNVIS) || defined(BROKEN_STRNVIS) #include #include #include "vis.h" #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define isvisible(c) \ (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ (flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) || \ ((flag & VIS_SP) == 0 && (c) == ' ') || \ ((flag & VIS_TAB) == 0 && (c) == '\t') || \ ((flag & VIS_NL) == 0 && (c) == '\n') || \ ((flag & VIS_SAFE) && ((c) == '\b' || \ (c) == '\007' || (c) == '\r' || \ isgraph((u_char)(c))))) /* * vis - visually encode characters */ char * vis(char *dst, int c, int flag, int nextc) { if (isvisible(c)) { *dst++ = c; if (c == '\\' && (flag & VIS_NOSLASH) == 0) *dst++ = '\\'; *dst = '\0'; return (dst); } if (flag & VIS_CSTYLE) { switch(c) { case '\n': *dst++ = '\\'; *dst++ = 'n'; goto done; case '\r': *dst++ = '\\'; *dst++ = 'r'; goto done; case '\b': *dst++ = '\\'; *dst++ = 'b'; goto done; case '\a': *dst++ = '\\'; *dst++ = 'a'; goto done; case '\v': *dst++ = '\\'; *dst++ = 'v'; goto done; case '\t': *dst++ = '\\'; *dst++ = 't'; goto done; case '\f': *dst++ = '\\'; *dst++ = 'f'; goto done; case ' ': *dst++ = '\\'; *dst++ = 's'; goto done; case '\0': *dst++ = '\\'; *dst++ = '0'; if (isoctal(nextc)) { *dst++ = '0'; *dst++ = '0'; } goto done; } } if (((c & 0177) == ' ') || (flag & VIS_OCTAL) || ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) { *dst++ = '\\'; *dst++ = ((u_char)c >> 6 & 07) + '0'; *dst++ = ((u_char)c >> 3 & 07) + '0'; *dst++ = ((u_char)c & 07) + '0'; goto done; } if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; if (c & 0200) { c &= 0177; *dst++ = 'M'; } if (iscntrl((u_char)c)) { *dst++ = '^'; if (c == 0177) *dst++ = '?'; else *dst++ = c + '@'; } else { *dst++ = '-'; *dst++ = c; } done: *dst = '\0'; return (dst); } /* * strvis, strnvis, strvisx - visually encode characters from src into dst * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, * is returned. * * Strnvis will write no more than siz-1 bytes (and will NULL terminate). * The number of bytes needed to fully encode the string is returned. * * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ int strvis(char *dst, const char *src, int flag) { char c; char *start; for (start = dst; (c = *src);) dst = vis(dst, c, flag, *++src); *dst = '\0'; return (dst - start); } int strnvis(char *dst, const char *src, size_t siz, int flag) { char *start, *end; char tbuf[5]; int c, i; i = 0; for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { if (isvisible(c)) { i = 1; *dst++ = c; if (c == '\\' && (flag & VIS_NOSLASH) == 0) { /* need space for the extra '\\' */ if (dst < end) *dst++ = '\\'; else { dst--; i = 2; break; } } src++; } else { i = vis(tbuf, c, flag, *++src) - tbuf; if (dst + i <= end) { memcpy(dst, tbuf, i); dst += i; } else { src--; break; } } } if (siz > 0) *dst = '\0'; if (dst + i > end) { /* adjust return value for truncation */ while ((c = *src)) dst += vis(tbuf, c, flag, *++src) - tbuf; } return (dst - start); } int strvisx(char *dst, const char *src, size_t len, int flag) { char c; char *start; for (start = dst; len > 1; len--) { c = *src; dst = vis(dst, c, flag, *++src); } if (len) dst = vis(dst, *src, flag, '\0'); *dst = '\0'; return (dst - start); } #endif openssh-7.2p2/openbsd-compat/vis.h010064400017500001750000000066641267006270000153530ustar00djmdjm/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /*- * Copyright (c) 1990 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. * * @(#)vis.h 5.9 (Berkeley) 4/3/91 */ /* OPENBSD ORIGINAL: include/vis.h */ #include "includes.h" #if !defined(HAVE_STRNVIS) || defined(BROKEN_STRNVIS) #ifndef _VIS_H_ #define _VIS_H_ #include #include /* * to select alternate encoding format */ #define VIS_OCTAL 0x01 /* use octal \ddd format */ #define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ /* * to alter set of characters encoded (default is to encode all * non-graphic except space, tab, and newline). */ #define VIS_SP 0x04 /* also encode space */ #define VIS_TAB 0x08 /* also encode tab */ #define VIS_NL 0x10 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) #define VIS_SAFE 0x20 /* only encode "unsafe" characters */ /* * other */ #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ #define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ /* * unvis return codes */ #define UNVIS_VALID 1 /* character valid */ #define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ #define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ #define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ #define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ /* * unvis flags */ #define UNVIS_END 1 /* no more characters */ char *vis(char *, int, int, int); int strvis(char *, const char *, int); int strnvis(char *, const char *, size_t, int) __attribute__ ((__bounded__(__string__,1,3))); int strvisx(char *, const char *, size_t, int) __attribute__ ((__bounded__(__string__,1,3))); int strunvis(char *, const char *); int unvis(char *, char, int *, int); ssize_t strnunvis(char *, const char *, size_t) __attribute__ ((__bounded__(__string__,1,3))); #endif /* !_VIS_H_ */ #endif /* !HAVE_STRNVIS || BROKEN_STRNVIS */ openssh-7.2p2/openbsd-compat/xcrypt.c010064400017500001750000000065461267006270000160750ustar00djmdjm/* * Copyright (c) 2003 Ben Lindstrom. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #include # if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE) # include # endif # ifdef __hpux # include # include # endif # ifdef HAVE_SECUREWARE # include # include # include # endif # if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) # include # endif # if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) # include # include # include # endif # if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) # include "md5crypt.h" # endif # if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) # include # define crypt DES_crypt # endif char * xcrypt(const char *password, const char *salt) { char *crypted; # ifdef HAVE_MD5_PASSWORDS if (is_md5_salt(salt)) crypted = md5_crypt(password, salt); else crypted = crypt(password, salt); # elif defined(__hpux) && !defined(HAVE_SECUREWARE) if (iscomsec()) crypted = bigcrypt(password, salt); else crypted = crypt(password, salt); # elif defined(HAVE_SECUREWARE) crypted = bigcrypt(password, salt); # else crypted = crypt(password, salt); # endif return crypted; } /* * Handle shadowed password systems in a cleaner way for portable * version. */ char * shadow_pw(struct passwd *pw) { char *pw_password = pw->pw_passwd; # if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) struct spwd *spw = getspnam(pw->pw_name); if (spw != NULL) pw_password = spw->sp_pwdp; # endif #ifdef USE_LIBIAF return(get_iaf_password(pw)); #endif # if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) struct passwd_adjunct *spw; if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) pw_password = spw->pwa_passwd; # elif defined(HAVE_SECUREWARE) struct pr_passwd *spw = getprpwnam(pw->pw_name); if (spw != NULL) pw_password = spw->ufld.fd_encrypt; # endif return pw_password; } openssh-7.2p2/openbsd-compat/xmmap.c010064400017500001750000000052161267006270000156570ustar00djmdjm/* * Copyright (c) 2002 Tim Rice. All rights reserved. * MAP_FAILED code by Solar Designer. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 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. */ /* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */ #include "includes.h" #include #ifdef HAVE_SYS_MMAN_H #include #endif #include #ifdef HAVE_FCNTL_H # include #endif #include #include #include #include #include #include "log.h" void * xmmap(size_t size) { #ifdef HAVE_MMAP void *address; # ifdef MAP_ANON address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, -1, (off_t)0); # else address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, open("/dev/zero", O_RDWR), (off_t)0); # endif #define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" if (address == (void *)MAP_FAILED) { char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; int tmpfd; mode_t old_umask; old_umask = umask(0177); tmpfd = mkstemp(tmpname); umask(old_umask); if (tmpfd == -1) fatal("mkstemp(\"%s\"): %s", MM_SWAP_TEMPLATE, strerror(errno)); unlink(tmpname); if (ftruncate(tmpfd, size) != 0) fatal("%s: ftruncate: %s", __func__, strerror(errno)); address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, tmpfd, (off_t)0); close(tmpfd); } return (address); #else fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", __func__); #endif /* HAVE_MMAP */ } openssh-7.2p2/openssh.xml.in010064400017500001750000000054271267006270000142700ustar00djmdjm openssh-7.2p2/opensshd.init.in010075500017500001750000000037611267006270000146010ustar00djmdjm#!@STARTUP_SCRIPT_SHELL@ # Donated code that was put under PD license. # # Stripped PRNGd out of it for the time being. umask 022 CAT=@CAT@ KILL=@KILL@ prefix=@prefix@ sysconfdir=@sysconfdir@ piddir=@piddir@ SSHD=$prefix/sbin/sshd PIDFILE=$piddir/sshd.pid PidFile=`grep "^PidFile" ${sysconfdir}/sshd_config | tr "=" " " | awk '{print $2}'` [ X$PidFile = X ] || PIDFILE=$PidFile SSH_KEYGEN=$prefix/bin/ssh-keygen HOST_KEY_RSA1=$sysconfdir/ssh_host_key HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key HOST_KEY_RSA=$sysconfdir/ssh_host_rsa_key @COMMENT_OUT_ECC@HOST_KEY_ECDSA=$sysconfdir/ssh_host_ecdsa_key HOST_KEY_ED25519=$sysconfdir/ssh_host_ed25519_key checkkeys() { if [ ! -f $HOST_KEY_RSA1 ]; then ${SSH_KEYGEN} -t rsa1 -f ${HOST_KEY_RSA1} -N "" fi if [ ! -f $HOST_KEY_DSA ]; then ${SSH_KEYGEN} -t dsa -f ${HOST_KEY_DSA} -N "" fi if [ ! -f $HOST_KEY_RSA ]; then ${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N "" fi @COMMENT_OUT_ECC@ if [ ! -f $HOST_KEY_ECDSA ]; then @COMMENT_OUT_ECC@ ${SSH_KEYGEN} -t ecdsa -f ${HOST_KEY_ECDSA} -N "" @COMMENT_OUT_ECC@ fi if [ ! -f $HOST_KEY_ED25519 ]; then ${SSH_KEYGEN} -t ed25519 -f ${HOST_KEY_ED25519} -N "" fi } stop_service() { if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then PID=`${CAT} ${PIDFILE}` fi if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then ${KILL} ${PID} else echo "Unable to read PID file" fi } start_service() { # XXX We really should check if the service is already going, but # XXX we will opt out at this time. - Bal # Check to see if we have keys that need to be made checkkeys # Start SSHD echo "starting $SSHD... \c" ; $SSHD sshd_rc=$? if [ $sshd_rc -ne 0 ]; then echo "$0: Error ${sshd_rc} starting ${SSHD}... bailing." exit $sshd_rc fi echo done. } case $1 in 'start') start_service ;; 'stop') stop_service ;; 'restart') stop_service start_service ;; *) echo "$0: usage: $0 {start|stop|restart}" ;; esac openssh-7.2p2/packet.c010064400017500001750000002416621267006270000131000ustar00djmdjm/* $OpenBSD: packet.c,v 1.229 2016/02/17 22:20:14 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * This file contains code implementing the packet protocol and communication * with the other side. This same code is used both on client and server side. * * 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, 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 /* MIN roundup */ #include #include "openbsd-compat/sys-queue.h" #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "buffer.h" /* typedefs XXX */ #include "key.h" /* typedefs XXX */ #include "xmalloc.h" #include "crc32.h" #include "deattack.h" #include "compat.h" #include "ssh1.h" #include "ssh2.h" #include "cipher.h" #include "sshkey.h" #include "kex.h" #include "digest.h" #include "mac.h" #include "log.h" #include "canohost.h" #include "misc.h" #include "channels.h" #include "ssh.h" #include "packet.h" #include "ssherr.h" #include "sshbuf.h" #ifdef PACKET_DEBUG #define DBG(x) x #else #define DBG(x) #endif #define PACKET_MAX_SIZE (256 * 1024) struct packet_state { u_int32_t seqnr; u_int32_t packets; u_int64_t blocks; u_int64_t bytes; }; struct packet { TAILQ_ENTRY(packet) next; u_char type; struct sshbuf *payload; }; struct session_state { /* * This variable contains the file descriptors used for * communicating with the other side. connection_in is used for * reading; connection_out for writing. These can be the same * descriptor, in which case it is assumed to be a socket. */ int connection_in; int connection_out; /* Protocol flags for the remote side. */ u_int remote_protocol_flags; /* Encryption context for receiving data. Only used for decryption. */ struct sshcipher_ctx receive_context; /* Encryption context for sending data. Only used for encryption. */ struct sshcipher_ctx send_context; /* Buffer for raw input data from the socket. */ struct sshbuf *input; /* Buffer for raw output data going to the socket. */ struct sshbuf *output; /* Buffer for the partial outgoing packet being constructed. */ struct sshbuf *outgoing_packet; /* Buffer for the incoming packet currently being processed. */ struct sshbuf *incoming_packet; /* Scratch buffer for packet compression/decompression. */ struct sshbuf *compression_buffer; /* Incoming/outgoing compression dictionaries */ z_stream compression_in_stream; z_stream compression_out_stream; int compression_in_started; int compression_out_started; int compression_in_failures; int compression_out_failures; /* * Flag indicating whether packet compression/decompression is * enabled. */ int packet_compression; /* default maximum packet size */ u_int max_packet_size; /* Flag indicating whether this module has been initialized. */ int initialized; /* Set to true if the connection is interactive. */ int interactive_mode; /* Set to true if we are the server side. */ int server_side; /* Set to true if we are authenticated. */ int after_authentication; int keep_alive_timeouts; /* The maximum time that we will wait to send or receive a packet */ int packet_timeout_ms; /* Session key information for Encryption and MAC */ struct newkeys *newkeys[MODE_MAX]; struct packet_state p_read, p_send; /* Volume-based rekeying */ u_int64_t max_blocks_in, max_blocks_out, rekey_limit; /* Time-based rekeying */ u_int32_t rekey_interval; /* how often in seconds */ time_t rekey_time; /* time of last rekeying */ /* Session key for protocol v1 */ u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; u_int ssh1_keylen; /* roundup current message to extra_pad bytes */ u_char extra_pad; /* XXX discard incoming data after MAC error */ u_int packet_discard; struct sshmac *packet_discard_mac; /* Used in packet_read_poll2() */ u_int packlen; /* Used in packet_send2 */ int rekeying; /* Used in packet_set_interactive */ int set_interactive_called; /* Used in packet_set_maxsize */ int set_maxsize_called; /* One-off warning about weak ciphers */ int cipher_warning_done; /* SSH1 CRC compensation attack detector */ struct deattack_ctx deattack; TAILQ_HEAD(, packet) outgoing; }; struct ssh * ssh_alloc_session_state(void) { struct ssh *ssh = NULL; struct session_state *state = NULL; if ((ssh = calloc(1, sizeof(*ssh))) == NULL || (state = calloc(1, sizeof(*state))) == NULL || (state->input = sshbuf_new()) == NULL || (state->output = sshbuf_new()) == NULL || (state->outgoing_packet = sshbuf_new()) == NULL || (state->incoming_packet = sshbuf_new()) == NULL) goto fail; TAILQ_INIT(&state->outgoing); TAILQ_INIT(&ssh->private_keys); TAILQ_INIT(&ssh->public_keys); state->connection_in = -1; state->connection_out = -1; state->max_packet_size = 32768; state->packet_timeout_ms = -1; state->p_send.packets = state->p_read.packets = 0; state->initialized = 1; /* * ssh_packet_send2() needs to queue packets until * we've done the initial key exchange. */ state->rekeying = 1; ssh->state = state; return ssh; fail: if (state) { sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->incoming_packet); sshbuf_free(state->outgoing_packet); free(state); } free(ssh); return NULL; } /* Returns nonzero if rekeying is in progress */ int ssh_packet_is_rekeying(struct ssh *ssh) { return compat20 && (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); } /* * Sets the descriptors used for communication. Disables encryption until * packet_set_encryption_key is called. */ struct ssh * ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) { struct session_state *state; const struct sshcipher *none = cipher_by_name("none"); int r; if (none == NULL) { error("%s: cannot load cipher 'none'", __func__); return NULL; } if (ssh == NULL) ssh = ssh_alloc_session_state(); if (ssh == NULL) { error("%s: cound not allocate state", __func__); return NULL; } state = ssh->state; state->connection_in = fd_in; state->connection_out = fd_out; if ((r = cipher_init(&state->send_context, none, (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || (r = cipher_init(&state->receive_context, none, (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { error("%s: cipher_init failed: %s", __func__, ssh_err(r)); free(ssh); return NULL; } state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; deattack_init(&state->deattack); /* * Cache the IP address of the remote connection for use in error * messages that might be generated after the connection has closed. */ (void)ssh_remote_ipaddr(ssh); return ssh; } void ssh_packet_set_timeout(struct ssh *ssh, int timeout, int count) { struct session_state *state = ssh->state; if (timeout <= 0 || count <= 0) { state->packet_timeout_ms = -1; return; } if ((INT_MAX / 1000) / count < timeout) state->packet_timeout_ms = INT_MAX; else state->packet_timeout_ms = timeout * count * 1000; } int ssh_packet_stop_discard(struct ssh *ssh) { struct session_state *state = ssh->state; int r; if (state->packet_discard_mac) { char buf[1024]; memset(buf, 'a', sizeof(buf)); while (sshbuf_len(state->incoming_packet) < PACKET_MAX_SIZE) if ((r = sshbuf_put(state->incoming_packet, buf, sizeof(buf))) != 0) return r; (void) mac_compute(state->packet_discard_mac, state->p_read.seqnr, sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, NULL, 0); } logit("Finished discarding for %.200s port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); return SSH_ERR_MAC_INVALID; } static int ssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc, struct sshmac *mac, u_int packet_length, u_int discard) { struct session_state *state = ssh->state; int r; if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) { if ((r = sshpkt_disconnect(ssh, "Packet corrupt")) != 0) return r; return SSH_ERR_MAC_INVALID; } if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) state->packet_discard_mac = mac; if (sshbuf_len(state->input) >= discard && (r = ssh_packet_stop_discard(ssh)) != 0) return r; state->packet_discard = discard - sshbuf_len(state->input); return 0; } /* Returns 1 if remote host is connected via socket, 0 if not. */ int ssh_packet_connection_is_on_socket(struct ssh *ssh) { struct session_state *state = ssh->state; struct sockaddr_storage from, to; socklen_t fromlen, tolen; /* filedescriptors in and out are the same, so it's a socket */ if (state->connection_in == state->connection_out) return 1; fromlen = sizeof(from); memset(&from, 0, sizeof(from)); if (getpeername(state->connection_in, (struct sockaddr *)&from, &fromlen) < 0) return 0; tolen = sizeof(to); memset(&to, 0, sizeof(to)); if (getpeername(state->connection_out, (struct sockaddr *)&to, &tolen) < 0) return 0; if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) return 0; if (from.ss_family != AF_INET && from.ss_family != AF_INET6) return 0; return 1; } void ssh_packet_get_bytes(struct ssh *ssh, u_int64_t *ibytes, u_int64_t *obytes) { if (ibytes) *ibytes = ssh->state->p_read.bytes; if (obytes) *obytes = ssh->state->p_send.bytes; } int ssh_packet_connection_af(struct ssh *ssh) { struct sockaddr_storage to; socklen_t tolen = sizeof(to); memset(&to, 0, sizeof(to)); if (getsockname(ssh->state->connection_out, (struct sockaddr *)&to, &tolen) < 0) return 0; #ifdef IPV4_IN_IPV6 if (to.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) return AF_INET; #endif return to.ss_family; } /* Sets the connection into non-blocking mode. */ void ssh_packet_set_nonblocking(struct ssh *ssh) { /* Set the socket into non-blocking mode. */ set_nonblock(ssh->state->connection_in); if (ssh->state->connection_out != ssh->state->connection_in) set_nonblock(ssh->state->connection_out); } /* Returns the socket used for reading. */ int ssh_packet_get_connection_in(struct ssh *ssh) { return ssh->state->connection_in; } /* Returns the descriptor used for writing. */ int ssh_packet_get_connection_out(struct ssh *ssh) { return ssh->state->connection_out; } /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. */ const char * ssh_remote_ipaddr(struct ssh *ssh) { const int sock = ssh->state->connection_in; /* Check whether we have cached the ipaddr. */ if (ssh->remote_ipaddr == NULL) { if (ssh_packet_connection_is_on_socket(ssh)) { ssh->remote_ipaddr = get_peer_ipaddr(sock); ssh->remote_port = get_sock_port(sock, 0); } else { ssh->remote_ipaddr = strdup("UNKNOWN"); ssh->remote_port = 0; } } return ssh->remote_ipaddr; } /* Returns the port number of the remote host. */ int ssh_remote_port(struct ssh *ssh) { (void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */ return ssh->remote_port; } /* Closes the connection and clears and frees internal data structures. */ void ssh_packet_close(struct ssh *ssh) { struct session_state *state = ssh->state; int r; u_int mode; if (!state->initialized) return; state->initialized = 0; if (state->connection_in == state->connection_out) { shutdown(state->connection_out, SHUT_RDWR); close(state->connection_out); } else { close(state->connection_in); close(state->connection_out); } sshbuf_free(state->input); sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); sshbuf_free(state->incoming_packet); for (mode = 0; mode < MODE_MAX; mode++) kex_free_newkeys(state->newkeys[mode]); if (state->compression_buffer) { sshbuf_free(state->compression_buffer); if (state->compression_out_started) { z_streamp stream = &state->compression_out_stream; debug("compress outgoing: " "raw data %llu, compressed %llu, factor %.2f", (unsigned long long)stream->total_in, (unsigned long long)stream->total_out, stream->total_in == 0 ? 0.0 : (double) stream->total_out / stream->total_in); if (state->compression_out_failures == 0) deflateEnd(stream); } if (state->compression_in_started) { z_streamp stream = &state->compression_out_stream; debug("compress incoming: " "raw data %llu, compressed %llu, factor %.2f", (unsigned long long)stream->total_out, (unsigned long long)stream->total_in, stream->total_out == 0 ? 0.0 : (double) stream->total_in / stream->total_out); if (state->compression_in_failures == 0) inflateEnd(stream); } } if ((r = cipher_cleanup(&state->send_context)) != 0) error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); if ((r = cipher_cleanup(&state->receive_context)) != 0) error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); free(ssh->remote_ipaddr); ssh->remote_ipaddr = NULL; free(ssh->state); ssh->state = NULL; } /* Sets remote side protocol flags. */ void ssh_packet_set_protocol_flags(struct ssh *ssh, u_int protocol_flags) { ssh->state->remote_protocol_flags = protocol_flags; } /* Returns the remote protocol flags set earlier by the above function. */ u_int ssh_packet_get_protocol_flags(struct ssh *ssh) { return ssh->state->remote_protocol_flags; } /* * Starts packet compression from the next packet on in both directions. * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */ static int ssh_packet_init_compression(struct ssh *ssh) { if (!ssh->state->compression_buffer && ((ssh->state->compression_buffer = sshbuf_new()) == NULL)) return SSH_ERR_ALLOC_FAIL; return 0; } static int start_compression_out(struct ssh *ssh, int level) { if (level < 1 || level > 9) return SSH_ERR_INVALID_ARGUMENT; debug("Enabling compression at level %d.", level); if (ssh->state->compression_out_started == 1) deflateEnd(&ssh->state->compression_out_stream); switch (deflateInit(&ssh->state->compression_out_stream, level)) { case Z_OK: ssh->state->compression_out_started = 1; break; case Z_MEM_ERROR: return SSH_ERR_ALLOC_FAIL; default: return SSH_ERR_INTERNAL_ERROR; } return 0; } static int start_compression_in(struct ssh *ssh) { if (ssh->state->compression_in_started == 1) inflateEnd(&ssh->state->compression_in_stream); switch (inflateInit(&ssh->state->compression_in_stream)) { case Z_OK: ssh->state->compression_in_started = 1; break; case Z_MEM_ERROR: return SSH_ERR_ALLOC_FAIL; default: return SSH_ERR_INTERNAL_ERROR; } return 0; } int ssh_packet_start_compression(struct ssh *ssh, int level) { int r; if (ssh->state->packet_compression && !compat20) return SSH_ERR_INTERNAL_ERROR; ssh->state->packet_compression = 1; if ((r = ssh_packet_init_compression(ssh)) != 0 || (r = start_compression_in(ssh)) != 0 || (r = start_compression_out(ssh, level)) != 0) return r; return 0; } /* XXX remove need for separate compression buffer */ static int compress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) { u_char buf[4096]; int r, status; if (ssh->state->compression_out_started != 1) return SSH_ERR_INTERNAL_ERROR; /* This case is not handled below. */ if (sshbuf_len(in) == 0) return 0; /* Input is the contents of the input buffer. */ if ((ssh->state->compression_out_stream.next_in = sshbuf_mutable_ptr(in)) == NULL) return SSH_ERR_INTERNAL_ERROR; ssh->state->compression_out_stream.avail_in = sshbuf_len(in); /* Loop compressing until deflate() returns with avail_out != 0. */ do { /* Set up fixed-size output buffer. */ ssh->state->compression_out_stream.next_out = buf; ssh->state->compression_out_stream.avail_out = sizeof(buf); /* Compress as much data into the buffer as possible. */ status = deflate(&ssh->state->compression_out_stream, Z_PARTIAL_FLUSH); switch (status) { case Z_MEM_ERROR: return SSH_ERR_ALLOC_FAIL; case Z_OK: /* Append compressed data to output_buffer. */ if ((r = sshbuf_put(out, buf, sizeof(buf) - ssh->state->compression_out_stream.avail_out)) != 0) return r; break; case Z_STREAM_ERROR: default: ssh->state->compression_out_failures++; return SSH_ERR_INVALID_FORMAT; } } while (ssh->state->compression_out_stream.avail_out == 0); return 0; } static int uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) { u_char buf[4096]; int r, status; if (ssh->state->compression_in_started != 1) return SSH_ERR_INTERNAL_ERROR; if ((ssh->state->compression_in_stream.next_in = sshbuf_mutable_ptr(in)) == NULL) return SSH_ERR_INTERNAL_ERROR; ssh->state->compression_in_stream.avail_in = sshbuf_len(in); for (;;) { /* Set up fixed-size output buffer. */ ssh->state->compression_in_stream.next_out = buf; ssh->state->compression_in_stream.avail_out = sizeof(buf); status = inflate(&ssh->state->compression_in_stream, Z_PARTIAL_FLUSH); switch (status) { case Z_OK: if ((r = sshbuf_put(out, buf, sizeof(buf) - ssh->state->compression_in_stream.avail_out)) != 0) return r; 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 0; case Z_DATA_ERROR: return SSH_ERR_INVALID_FORMAT; case Z_MEM_ERROR: return SSH_ERR_ALLOC_FAIL; case Z_STREAM_ERROR: default: ssh->state->compression_in_failures++; return SSH_ERR_INTERNAL_ERROR; } } /* NOTREACHED */ } /* Serialise compression state into a blob for privsep */ static int ssh_packet_get_compress_state(struct sshbuf *m, struct ssh *ssh) { struct session_state *state = ssh->state; struct sshbuf *b; int r; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if (state->compression_in_started) { if ((r = sshbuf_put_string(b, &state->compression_in_stream, sizeof(state->compression_in_stream))) != 0) goto out; } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) goto out; if (state->compression_out_started) { if ((r = sshbuf_put_string(b, &state->compression_out_stream, sizeof(state->compression_out_stream))) != 0) goto out; } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) goto out; r = sshbuf_put_stringb(m, b); out: sshbuf_free(b); return r; } /* Deserialise compression state from a blob for privsep */ static int ssh_packet_set_compress_state(struct ssh *ssh, struct sshbuf *m) { struct session_state *state = ssh->state; struct sshbuf *b = NULL; int r; const u_char *inblob, *outblob; size_t inl, outl; if ((r = sshbuf_froms(m, &b)) != 0) goto out; if ((r = sshbuf_get_string_direct(b, &inblob, &inl)) != 0 || (r = sshbuf_get_string_direct(b, &outblob, &outl)) != 0) goto out; if (inl == 0) state->compression_in_started = 0; else if (inl != sizeof(state->compression_in_stream)) { r = SSH_ERR_INTERNAL_ERROR; goto out; } else { state->compression_in_started = 1; memcpy(&state->compression_in_stream, inblob, inl); } if (outl == 0) state->compression_out_started = 0; else if (outl != sizeof(state->compression_out_stream)) { r = SSH_ERR_INTERNAL_ERROR; goto out; } else { state->compression_out_started = 1; memcpy(&state->compression_out_stream, outblob, outl); } r = 0; out: sshbuf_free(b); return r; } void ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx, void *(*allocfunc)(void *, u_int, u_int), void (*freefunc)(void *, void *)) { ssh->state->compression_out_stream.zalloc = (alloc_func)allocfunc; ssh->state->compression_out_stream.zfree = (free_func)freefunc; ssh->state->compression_out_stream.opaque = ctx; ssh->state->compression_in_stream.zalloc = (alloc_func)allocfunc; ssh->state->compression_in_stream.zfree = (free_func)freefunc; ssh->state->compression_in_stream.opaque = ctx; } /* * Causes any further packets to be encrypted using the given key. The same * key is used for both sending and reception. However, both directions are * encrypted independently of each other. */ void ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) { #ifndef WITH_SSH1 fatal("no SSH protocol 1 support"); #else /* WITH_SSH1 */ struct session_state *state = ssh->state; const struct sshcipher *cipher = cipher_by_number(number); int r; const char *wmsg; if (cipher == NULL) fatal("%s: unknown cipher number %d", __func__, number); if (keylen < 20) fatal("%s: keylen too small: %d", __func__, keylen); if (keylen > SSH_SESSION_KEY_LENGTH) fatal("%s: keylen too big: %d", __func__, keylen); memcpy(state->ssh1_key, key, keylen); state->ssh1_keylen = keylen; if ((r = cipher_init(&state->send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT)) != 0 || (r = cipher_init(&state->receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT) != 0)) fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); if (!state->cipher_warning_done && ((wmsg = cipher_warning_message(&state->send_context)) != NULL || (wmsg = cipher_warning_message(&state->send_context)) != NULL)) { error("Warning: %s", wmsg); state->cipher_warning_done = 1; } #endif /* WITH_SSH1 */ } /* * Finalizes and sends the packet. If the encryption key has been set, * encrypts the packet before sending. */ int ssh_packet_send1(struct ssh *ssh) { struct session_state *state = ssh->state; u_char buf[8], *cp; int r, padding, len; u_int checksum; /* * If using packet compression, compress the payload of the outgoing * packet. */ if (state->packet_compression) { sshbuf_reset(state->compression_buffer); /* Skip padding. */ if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0) goto out; /* padding */ if ((r = sshbuf_put(state->compression_buffer, "\0\0\0\0\0\0\0\0", 8)) != 0) goto out; if ((r = compress_buffer(ssh, state->outgoing_packet, state->compression_buffer)) != 0) goto out; sshbuf_reset(state->outgoing_packet); if ((r = sshbuf_putb(state->outgoing_packet, state->compression_buffer)) != 0) goto out; } /* Compute packet length without padding (add checksum, remove padding). */ len = sshbuf_len(state->outgoing_packet) + 4 - 8; /* Insert padding. Initialized to zero in packet_start1() */ padding = 8 - len % 8; if (!state->send_context.plaintext) { cp = sshbuf_mutable_ptr(state->outgoing_packet); if (cp == NULL) { r = SSH_ERR_INTERNAL_ERROR; goto out; } arc4random_buf(cp + 8 - padding, padding); } if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0) goto out; /* Add check bytes. */ checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet), sshbuf_len(state->outgoing_packet)); POKE_U32(buf, checksum); if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0) goto out; #ifdef PACKET_DEBUG fprintf(stderr, "packet_send plain: "); sshbuf_dump(state->outgoing_packet, stderr); #endif /* Append to output. */ POKE_U32(buf, len); if ((r = sshbuf_put(state->output, buf, 4)) != 0) goto out; if ((r = sshbuf_reserve(state->output, sshbuf_len(state->outgoing_packet), &cp)) != 0) goto out; if ((r = cipher_crypt(&state->send_context, 0, cp, sshbuf_ptr(state->outgoing_packet), sshbuf_len(state->outgoing_packet), 0, 0)) != 0) goto out; #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); sshbuf_dump(state->output, stderr); #endif state->p_send.packets++; state->p_send.bytes += len + sshbuf_len(state->outgoing_packet); sshbuf_reset(state->outgoing_packet); /* * Note that the packet is now only buffered in output. It won't be * actually sent until ssh_packet_write_wait or ssh_packet_write_poll * is called. */ r = 0; out: return r; } int ssh_set_newkeys(struct ssh *ssh, int mode) { struct session_state *state = ssh->state; struct sshenc *enc; struct sshmac *mac; struct sshcomp *comp; struct sshcipher_ctx *cc; u_int64_t *max_blocks; const char *wmsg; int r, crypt_type; debug2("set_newkeys: mode %d", mode); if (mode == MODE_OUT) { cc = &state->send_context; crypt_type = CIPHER_ENCRYPT; state->p_send.packets = state->p_send.blocks = 0; max_blocks = &state->max_blocks_out; } else { cc = &state->receive_context; crypt_type = CIPHER_DECRYPT; state->p_read.packets = state->p_read.blocks = 0; max_blocks = &state->max_blocks_in; } if (state->newkeys[mode] != NULL) { debug("set_newkeys: rekeying, input %llu bytes %llu blocks, " "output %llu bytes %llu blocks", (unsigned long long)state->p_read.bytes, (unsigned long long)state->p_read.blocks, (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; mac = &state->newkeys[mode]->mac; comp = &state->newkeys[mode]->comp; mac_clear(mac); explicit_bzero(enc->iv, enc->iv_len); explicit_bzero(enc->key, enc->key_len); explicit_bzero(mac->key, mac->key_len); free(enc->name); free(enc->iv); free(enc->key); free(mac->name); free(mac->key); free(comp->name); free(state->newkeys[mode]); } /* move newkeys from kex to state */ if ((state->newkeys[mode] = ssh->kex->newkeys[mode]) == NULL) return SSH_ERR_INTERNAL_ERROR; ssh->kex->newkeys[mode] = NULL; enc = &state->newkeys[mode]->enc; mac = &state->newkeys[mode]->mac; comp = &state->newkeys[mode]->comp; if (cipher_authlen(enc->cipher) == 0) { if ((r = mac_init(mac)) != 0) return r; } mac->enabled = 1; DBG(debug("cipher_init_context: %d", mode)); if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len, enc->iv, enc->iv_len, crypt_type)) != 0) return r; if (!state->cipher_warning_done && (wmsg = cipher_warning_message(cc)) != NULL) { error("Warning: %s", wmsg); state->cipher_warning_done = 1; } /* Deleting the keys does not gain extra security */ /* explicit_bzero(enc->iv, enc->block_size); explicit_bzero(enc->key, enc->key_len); explicit_bzero(mac->key, mac->key_len); */ if ((comp->type == COMP_ZLIB || (comp->type == COMP_DELAYED && state->after_authentication)) && comp->enabled == 0) { if ((r = ssh_packet_init_compression(ssh)) < 0) return r; if (mode == MODE_OUT) { if ((r = start_compression_out(ssh, 6)) != 0) return r; } else { if ((r = start_compression_in(ssh)) != 0) return r; } comp->enabled = 1; } /* * The 2^(blocksize*2) limit is too expensive for 3DES, * blowfish, etc, so enforce a 1GB limit for small blocksizes. */ if (enc->block_size >= 16) *max_blocks = (u_int64_t)1 << (enc->block_size*2); else *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; if (state->rekey_limit) *max_blocks = MIN(*max_blocks, state->rekey_limit / enc->block_size); debug("rekey after %llu blocks", (unsigned long long)*max_blocks); return 0; } #define MAX_PACKETS (1U<<31) static int ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) { struct session_state *state = ssh->state; u_int32_t out_blocks; /* XXX client can't cope with rekeying pre-auth */ if (!state->after_authentication) return 0; /* Haven't keyed yet or KEX in progress. */ if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) return 0; /* Peer can't rekey */ if (ssh->compat & SSH_BUG_NOREKEY) return 0; /* * Permit one packet in or out per rekey - this allows us to * make progress when rekey limits are very small. */ if (state->p_send.packets == 0 && state->p_read.packets == 0) return 0; /* Time-based rekeying */ if (state->rekey_interval != 0 && state->rekey_time + state->rekey_interval <= monotime()) return 1; /* Always rekey when MAX_PACKETS sent in either direction */ if (state->p_send.packets > MAX_PACKETS || state->p_read.packets > MAX_PACKETS) return 1; /* Rekey after (cipher-specific) maxiumum blocks */ out_blocks = roundup(outbound_packet_len, state->newkeys[MODE_OUT]->enc.block_size); return (state->max_blocks_out && (state->p_send.blocks + out_blocks > state->max_blocks_out)) || (state->max_blocks_in && (state->p_read.blocks > state->max_blocks_in)); } /* * Delayed compression for SSH2 is enabled after authentication: * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. */ static int ssh_packet_enable_delayed_compress(struct ssh *ssh) { struct session_state *state = ssh->state; struct sshcomp *comp = NULL; int r, mode; /* * Remember that we are past the authentication step, so rekeying * with COMP_DELAYED will turn on compression immediately. */ state->after_authentication = 1; for (mode = 0; mode < MODE_MAX; mode++) { /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ if (state->newkeys[mode] == NULL) continue; comp = &state->newkeys[mode]->comp; if (comp && !comp->enabled && comp->type == COMP_DELAYED) { if ((r = ssh_packet_init_compression(ssh)) != 0) return r; if (mode == MODE_OUT) { if ((r = start_compression_out(ssh, 6)) != 0) return r; } else { if ((r = start_compression_in(ssh)) != 0) return r; } comp->enabled = 1; } } return 0; } /* Used to mute debug logging for noisy packet types */ static int ssh_packet_log_type(u_char type) { switch (type) { case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_WINDOW_ADJUST: return 0; default: return 1; } } /* * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) */ int ssh_packet_send2_wrapped(struct ssh *ssh) { struct session_state *state = ssh->state; u_char type, *cp, macbuf[SSH_DIGEST_MAX_LENGTH]; u_char padlen, pad = 0; u_int authlen = 0, aadlen = 0; u_int len; struct sshenc *enc = NULL; struct sshmac *mac = NULL; struct sshcomp *comp = NULL; int r, block_size; if (state->newkeys[MODE_OUT] != NULL) { enc = &state->newkeys[MODE_OUT]->enc; mac = &state->newkeys[MODE_OUT]->mac; comp = &state->newkeys[MODE_OUT]->comp; /* disable mac for authenticated encryption */ if ((authlen = cipher_authlen(enc->cipher)) != 0) mac = NULL; } block_size = enc ? enc->block_size : 8; aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; type = (sshbuf_ptr(state->outgoing_packet))[5]; if (ssh_packet_log_type(type)) debug3("send packet: type %u", type); #ifdef PACKET_DEBUG fprintf(stderr, "plain: "); sshbuf_dump(state->outgoing_packet, stderr); #endif if (comp && comp->enabled) { len = sshbuf_len(state->outgoing_packet); /* skip header, compress only payload */ if ((r = sshbuf_consume(state->outgoing_packet, 5)) != 0) goto out; sshbuf_reset(state->compression_buffer); if ((r = compress_buffer(ssh, state->outgoing_packet, state->compression_buffer)) != 0) goto out; sshbuf_reset(state->outgoing_packet); if ((r = sshbuf_put(state->outgoing_packet, "\0\0\0\0\0", 5)) != 0 || (r = sshbuf_putb(state->outgoing_packet, state->compression_buffer)) != 0) goto out; DBG(debug("compression: raw %d compressed %zd", len, sshbuf_len(state->outgoing_packet))); } /* sizeof (packet_len + pad_len + payload) */ len = sshbuf_len(state->outgoing_packet); /* * calc size of padding, alloc space, get random data, * minimum padding is 4 bytes */ len -= aadlen; /* packet length is not encrypted for EtM modes */ padlen = block_size - (len % block_size); if (padlen < 4) padlen += block_size; if (state->extra_pad) { /* will wrap if extra_pad+padlen > 255 */ state->extra_pad = roundup(state->extra_pad, block_size); pad = state->extra_pad - ((len + padlen) % state->extra_pad); DBG(debug3("%s: adding %d (len %d padlen %d extra_pad %d)", __func__, pad, len, padlen, state->extra_pad)); padlen += pad; state->extra_pad = 0; } if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) goto out; if (enc && !state->send_context.plaintext) { /* random padding */ arc4random_buf(cp, padlen); } else { /* clear padding */ explicit_bzero(cp, padlen); } /* sizeof (packet_len + pad_len + payload + padding) */ len = sshbuf_len(state->outgoing_packet); cp = sshbuf_mutable_ptr(state->outgoing_packet); if (cp == NULL) { r = SSH_ERR_INTERNAL_ERROR; goto out; } /* packet_length includes payload, padding and padding length field */ POKE_U32(cp, len - 4); cp[4] = padlen; DBG(debug("send: len %d (includes padlen %d, aadlen %d)", len, padlen, aadlen)); /* compute MAC over seqnr and packet(length fields, payload, padding) */ if (mac && mac->enabled && !mac->etm) { if ((r = mac_compute(mac, state->p_send.seqnr, sshbuf_ptr(state->outgoing_packet), len, macbuf, sizeof(macbuf))) != 0) goto out; DBG(debug("done calc MAC out #%d", state->p_send.seqnr)); } /* encrypt packet and append to output buffer. */ if ((r = sshbuf_reserve(state->output, sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) goto out; if ((r = cipher_crypt(&state->send_context, state->p_send.seqnr, cp, sshbuf_ptr(state->outgoing_packet), len - aadlen, aadlen, authlen)) != 0) goto out; /* append unencrypted MAC */ if (mac && mac->enabled) { if (mac->etm) { /* EtM: compute mac over aadlen + cipher text */ if ((r = mac_compute(mac, state->p_send.seqnr, cp, len, macbuf, sizeof(macbuf))) != 0) goto out; DBG(debug("done calc MAC(EtM) out #%d", state->p_send.seqnr)); } if ((r = sshbuf_put(state->output, macbuf, mac->mac_len)) != 0) goto out; } #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); sshbuf_dump(state->output, stderr); #endif /* increment sequence number for outgoing packets */ if (++state->p_send.seqnr == 0) logit("outgoing seqnr wraps around"); if (++state->p_send.packets == 0) if (!(ssh->compat & SSH_BUG_NOREKEY)) return SSH_ERR_NEED_REKEY; state->p_send.blocks += len / block_size; state->p_send.bytes += len; sshbuf_reset(state->outgoing_packet); if (type == SSH2_MSG_NEWKEYS) r = ssh_set_newkeys(ssh, MODE_OUT); else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side) r = ssh_packet_enable_delayed_compress(ssh); else r = 0; out: return r; } /* returns non-zero if the specified packet type is usec by KEX */ static int ssh_packet_type_is_kex(u_char type) { return type >= SSH2_MSG_TRANSPORT_MIN && type <= SSH2_MSG_TRANSPORT_MAX && type != SSH2_MSG_SERVICE_REQUEST && type != SSH2_MSG_SERVICE_ACCEPT && type != SSH2_MSG_EXT_INFO; } int ssh_packet_send2(struct ssh *ssh) { struct session_state *state = ssh->state; struct packet *p; u_char type; int r, need_rekey; if (sshbuf_len(state->outgoing_packet) < 6) return SSH_ERR_INTERNAL_ERROR; type = sshbuf_ptr(state->outgoing_packet)[5]; need_rekey = !ssh_packet_type_is_kex(type) && ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet)); /* * During rekeying we can only send key exchange messages. * Queue everything else. */ if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { if (need_rekey) debug3("%s: rekex triggered", __func__); debug("enqueue packet: %u", type); p = calloc(1, sizeof(*p)); if (p == NULL) return SSH_ERR_ALLOC_FAIL; p->type = type; p->payload = state->outgoing_packet; TAILQ_INSERT_TAIL(&state->outgoing, p, next); state->outgoing_packet = sshbuf_new(); if (state->outgoing_packet == NULL) return SSH_ERR_ALLOC_FAIL; if (need_rekey) { /* * This packet triggered a rekey, so send the * KEXINIT now. * NB. reenters this function via kex_start_rekex(). */ return kex_start_rekex(ssh); } return 0; } /* rekeying starts with sending KEXINIT */ if (type == SSH2_MSG_KEXINIT) state->rekeying = 1; if ((r = ssh_packet_send2_wrapped(ssh)) != 0) return r; /* after a NEWKEYS message we can send the complete queue */ if (type == SSH2_MSG_NEWKEYS) { state->rekeying = 0; state->rekey_time = monotime(); while ((p = TAILQ_FIRST(&state->outgoing))) { type = p->type; /* * If this packet triggers a rekex, then skip the * remaining packets in the queue for now. * NB. re-enters this function via kex_start_rekex. */ if (ssh_packet_need_rekeying(ssh, sshbuf_len(p->payload))) { debug3("%s: queued packet triggered rekex", __func__); return kex_start_rekex(ssh); } debug("dequeue packet: %u", type); sshbuf_free(state->outgoing_packet); state->outgoing_packet = p->payload; TAILQ_REMOVE(&state->outgoing, p, next); memset(p, 0, sizeof(*p)); free(p); if ((r = ssh_packet_send2_wrapped(ssh)) != 0) return r; } } return 0; } /* * Waits until a packet has been received, and returns its type. Note that * no other data is processed until this returns, so this function should not * be used during the interactive session. */ int ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { struct session_state *state = ssh->state; int len, r, ms_remain; fd_set *setp; char buf[8192]; struct timeval timeout, start, *timeoutp = NULL; DBG(debug("packet_read()")); setp = calloc(howmany(state->connection_in + 1, NFDBITS), sizeof(fd_mask)); if (setp == NULL) return SSH_ERR_ALLOC_FAIL; /* * Since we are blocking, ensure that all written packets have * been sent. */ if ((r = ssh_packet_write_wait(ssh)) != 0) goto out; /* Stay in the loop until we have received a complete packet. */ for (;;) { /* Try to read a packet from the buffer. */ r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); if (r != 0) break; if (!compat20 && ( *typep == SSH_SMSG_SUCCESS || *typep == SSH_SMSG_FAILURE || *typep == SSH_CMSG_EOF || *typep == SSH_CMSG_EXIT_CONFIRMATION)) if ((r = sshpkt_get_end(ssh)) != 0) break; /* If we got a packet, return it. */ if (*typep != SSH_MSG_NONE) break; /* * Otherwise, wait for some data to arrive, add it to the * buffer, and try again. */ memset(setp, 0, howmany(state->connection_in + 1, NFDBITS) * sizeof(fd_mask)); FD_SET(state->connection_in, setp); if (state->packet_timeout_ms > 0) { ms_remain = state->packet_timeout_ms; timeoutp = &timeout; } /* Wait for some data to arrive. */ for (;;) { if (state->packet_timeout_ms != -1) { ms_to_timeval(&timeout, ms_remain); gettimeofday(&start, NULL); } if ((r = select(state->connection_in + 1, setp, NULL, NULL, timeoutp)) >= 0) break; if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) break; if (state->packet_timeout_ms == -1) continue; ms_subtract_diff(&start, &ms_remain); if (ms_remain <= 0) { r = 0; break; } } if (r == 0) return SSH_ERR_CONN_TIMEOUT; /* Read data from the socket. */ len = read(state->connection_in, buf, sizeof(buf)); if (len == 0) { r = SSH_ERR_CONN_CLOSED; goto out; } if (len < 0) { r = SSH_ERR_SYSTEM_ERROR; goto out; } /* Append it to the buffer. */ if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) goto out; } out: free(setp); return r; } int ssh_packet_read(struct ssh *ssh) { u_char type; int r; if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) fatal("%s: %s", __func__, ssh_err(r)); return type; } /* * Waits until a packet has been received, verifies that its type matches * that given, and gives a fatal error and exits if there is a mismatch. */ int ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) { int r; u_char type; if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) return r; if (type != expected_type) { if ((r = sshpkt_disconnect(ssh, "Protocol error: expected packet type %d, got %d", expected_type, type)) != 0) return r; return SSH_ERR_PROTOCOL_ERROR; } return 0; } /* Checks if a full packet is available in the data received so far via * packet_process_incoming. If so, reads the packet; otherwise returns * SSH_MSG_NONE. This does not wait for data from the connection. * * SSH_MSG_DISCONNECT is handled specially here. Also, * SSH_MSG_IGNORE messages are skipped by this function and are never returned * to higher levels. */ int ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) { struct session_state *state = ssh->state; u_int len, padded_len; const char *emsg; const u_char *cp; u_char *p; u_int checksum, stored_checksum; int r; *typep = SSH_MSG_NONE; /* Check if input size is less than minimum packet size. */ if (sshbuf_len(state->input) < 4 + 8) return 0; /* Get length of incoming packet. */ len = PEEK_U32(sshbuf_ptr(state->input)); if (len < 1 + 2 + 2 || len > 256 * 1024) { if ((r = sshpkt_disconnect(ssh, "Bad packet length %u", len)) != 0) return r; return SSH_ERR_CONN_CORRUPT; } padded_len = (len + 8) & ~7; /* Check if the packet has been entirely received. */ if (sshbuf_len(state->input) < 4 + padded_len) return 0; /* The entire packet is in buffer. */ /* Consume packet length. */ if ((r = sshbuf_consume(state->input, 4)) != 0) goto out; /* * Cryptographic attack detector for ssh * (C)1998 CORE-SDI, Buenos Aires Argentina * Ariel Futoransky(futo@core-sdi.com) */ if (!state->receive_context.plaintext) { emsg = NULL; switch (detect_attack(&state->deattack, sshbuf_ptr(state->input), padded_len)) { case DEATTACK_OK: break; case DEATTACK_DETECTED: emsg = "crc32 compensation attack detected"; break; case DEATTACK_DOS_DETECTED: emsg = "deattack denial of service detected"; break; default: emsg = "deattack error"; break; } if (emsg != NULL) { error("%s", emsg); if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_CONN_CORRUPT; } } /* Decrypt data to incoming_packet. */ sshbuf_reset(state->incoming_packet); if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) goto out; if ((r = cipher_crypt(&state->receive_context, 0, p, sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) goto out; if ((r = sshbuf_consume(state->input, padded_len)) != 0) goto out; #ifdef PACKET_DEBUG fprintf(stderr, "read_poll plain: "); sshbuf_dump(state->incoming_packet, stderr); #endif /* Compute packet checksum. */ checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet), sshbuf_len(state->incoming_packet) - 4); /* Skip padding. */ if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0) goto out; /* Test check bytes. */ if (len != sshbuf_len(state->incoming_packet)) { error("%s: len %d != sshbuf_len %zd", __func__, len, sshbuf_len(state->incoming_packet)); if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_CONN_CORRUPT; } cp = sshbuf_ptr(state->incoming_packet) + len - 4; stored_checksum = PEEK_U32(cp); if (checksum != stored_checksum) { error("Corrupted check bytes on input"); if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_CONN_CORRUPT; } if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) goto out; if (state->packet_compression) { sshbuf_reset(state->compression_buffer); if ((r = uncompress_buffer(ssh, state->incoming_packet, state->compression_buffer)) != 0) goto out; sshbuf_reset(state->incoming_packet); if ((r = sshbuf_putb(state->incoming_packet, state->compression_buffer)) != 0) goto out; } state->p_read.packets++; state->p_read.bytes += padded_len + 4; if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) goto out; if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) { error("Invalid ssh1 packet type: %d", *typep); if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_PROTOCOL_ERROR; } r = 0; out: return r; } int ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { struct session_state *state = ssh->state; u_int padlen, need; u_char *cp, macbuf[SSH_DIGEST_MAX_LENGTH]; u_int maclen, aadlen = 0, authlen = 0, block_size; struct sshenc *enc = NULL; struct sshmac *mac = NULL; struct sshcomp *comp = NULL; int r; *typep = SSH_MSG_NONE; if (state->packet_discard) return 0; if (state->newkeys[MODE_IN] != NULL) { enc = &state->newkeys[MODE_IN]->enc; mac = &state->newkeys[MODE_IN]->mac; comp = &state->newkeys[MODE_IN]->comp; /* disable mac for authenticated encryption */ if ((authlen = cipher_authlen(enc->cipher)) != 0) mac = NULL; } maclen = mac && mac->enabled ? mac->mac_len : 0; block_size = enc ? enc->block_size : 8; aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; if (aadlen && state->packlen == 0) { if (cipher_get_length(&state->receive_context, &state->packlen, state->p_read.seqnr, sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) return 0; if (state->packlen < 1 + 4 || state->packlen > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG sshbuf_dump(state->input, stderr); #endif logit("Bad packet length %u.", state->packlen); if ((r = sshpkt_disconnect(ssh, "Packet corrupt")) != 0) return r; return SSH_ERR_CONN_CORRUPT; } sshbuf_reset(state->incoming_packet); } else if (state->packlen == 0) { /* * check if input size is less than the cipher block size, * decrypt first block and extract length of incoming packet */ if (sshbuf_len(state->input) < block_size) return 0; sshbuf_reset(state->incoming_packet); if ((r = sshbuf_reserve(state->incoming_packet, block_size, &cp)) != 0) goto out; if ((r = cipher_crypt(&state->receive_context, state->p_send.seqnr, cp, sshbuf_ptr(state->input), block_size, 0, 0)) != 0) goto out; state->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet)); if (state->packlen < 1 + 4 || state->packlen > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG fprintf(stderr, "input: \n"); sshbuf_dump(state->input, stderr); fprintf(stderr, "incoming_packet: \n"); sshbuf_dump(state->incoming_packet, stderr); #endif logit("Bad packet length %u.", state->packlen); return ssh_packet_start_discard(ssh, enc, mac, state->packlen, PACKET_MAX_SIZE); } if ((r = sshbuf_consume(state->input, block_size)) != 0) goto out; } DBG(debug("input: packet len %u", state->packlen+4)); if (aadlen) { /* only the payload is encrypted */ need = state->packlen; } else { /* * the payload size and the payload are encrypted, but we * have a partial packet of block_size bytes */ need = 4 + state->packlen - block_size; } DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d," " aadlen %d", block_size, need, maclen, authlen, aadlen)); if (need % block_size != 0) { logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); return ssh_packet_start_discard(ssh, enc, mac, state->packlen, PACKET_MAX_SIZE - block_size); } /* * check if the entire packet has been received and * decrypt into incoming_packet: * 'aadlen' bytes are unencrypted, but authenticated. * 'need' bytes are encrypted, followed by either * 'authlen' bytes of authentication tag or * 'maclen' bytes of message authentication code. */ if (sshbuf_len(state->input) < aadlen + need + authlen + maclen) return 0; #ifdef PACKET_DEBUG fprintf(stderr, "read_poll enc/full: "); sshbuf_dump(state->input, stderr); #endif /* EtM: compute mac over encrypted input */ if (mac && mac->enabled && mac->etm) { if ((r = mac_compute(mac, state->p_read.seqnr, sshbuf_ptr(state->input), aadlen + need, macbuf, sizeof(macbuf))) != 0) goto out; } if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, &cp)) != 0) goto out; if ((r = cipher_crypt(&state->receive_context, state->p_read.seqnr, cp, sshbuf_ptr(state->input), need, aadlen, authlen)) != 0) goto out; if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) goto out; /* * compute MAC over seqnr and packet, * increment sequence number for incoming packet */ if (mac && mac->enabled) { if (!mac->etm) if ((r = mac_compute(mac, state->p_read.seqnr, sshbuf_ptr(state->incoming_packet), sshbuf_len(state->incoming_packet), macbuf, sizeof(macbuf))) != 0) goto out; if (timingsafe_bcmp(macbuf, sshbuf_ptr(state->input), mac->mac_len) != 0) { logit("Corrupted MAC on input."); if (need > PACKET_MAX_SIZE) return SSH_ERR_INTERNAL_ERROR; return ssh_packet_start_discard(ssh, enc, mac, state->packlen, PACKET_MAX_SIZE - need); } DBG(debug("MAC #%d ok", state->p_read.seqnr)); if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) goto out; } if (seqnr_p != NULL) *seqnr_p = state->p_read.seqnr; if (++state->p_read.seqnr == 0) logit("incoming seqnr wraps around"); if (++state->p_read.packets == 0) if (!(ssh->compat & SSH_BUG_NOREKEY)) return SSH_ERR_NEED_REKEY; state->p_read.blocks += (state->packlen + 4) / block_size; state->p_read.bytes += state->packlen + 4; /* get padlen */ padlen = sshbuf_ptr(state->incoming_packet)[4]; DBG(debug("input: padlen %d", padlen)); if (padlen < 4) { if ((r = sshpkt_disconnect(ssh, "Corrupted padlen %d on input.", padlen)) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_CONN_CORRUPT; } /* skip packet size + padlen, discard padding */ if ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 || ((r = sshbuf_consume_end(state->incoming_packet, padlen)) != 0)) goto out; DBG(debug("input: len before de-compress %zd", sshbuf_len(state->incoming_packet))); if (comp && comp->enabled) { sshbuf_reset(state->compression_buffer); if ((r = uncompress_buffer(ssh, state->incoming_packet, state->compression_buffer)) != 0) goto out; sshbuf_reset(state->incoming_packet); if ((r = sshbuf_putb(state->incoming_packet, state->compression_buffer)) != 0) goto out; DBG(debug("input: len after de-compress %zd", sshbuf_len(state->incoming_packet))); } /* * get packet type, implies consume. * return length of payload (without type field) */ if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) goto out; if (ssh_packet_log_type(*typep)) debug3("receive packet: type %u", *typep); if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { if ((r = sshpkt_disconnect(ssh, "Invalid ssh2 packet type: %d", *typep)) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) return r; return SSH_ERR_PROTOCOL_ERROR; } if (*typep == SSH2_MSG_NEWKEYS) r = ssh_set_newkeys(ssh, MODE_IN); else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) r = ssh_packet_enable_delayed_compress(ssh); else r = 0; #ifdef PACKET_DEBUG fprintf(stderr, "read/plain[%d]:\r\n", *typep); sshbuf_dump(state->incoming_packet, stderr); #endif /* reset for next packet */ state->packlen = 0; /* do we need to rekey? */ if (ssh_packet_need_rekeying(ssh, 0)) { debug3("%s: rekex triggered", __func__); if ((r = kex_start_rekex(ssh)) != 0) return r; } out: return r; } int ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { struct session_state *state = ssh->state; u_int reason, seqnr; int r; u_char *msg; for (;;) { msg = NULL; if (compat20) { r = ssh_packet_read_poll2(ssh, typep, seqnr_p); if (r != 0) return r; if (*typep) { state->keep_alive_timeouts = 0; DBG(debug("received packet type %d", *typep)); } switch (*typep) { case SSH2_MSG_IGNORE: debug3("Received SSH2_MSG_IGNORE"); break; case SSH2_MSG_DEBUG: if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { free(msg); return r; } debug("Remote: %.900s", msg); free(msg); break; case SSH2_MSG_DISCONNECT: if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) return r; /* Ignore normal client exit notifications */ do_log2(ssh->state->server_side && reason == SSH2_DISCONNECT_BY_APPLICATION ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, "Received disconnect from %s port %d:" "%u: %.400s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), reason, msg); free(msg); return SSH_ERR_DISCONNECTED; case SSH2_MSG_UNIMPLEMENTED: if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) return r; debug("Received SSH2_MSG_UNIMPLEMENTED for %u", seqnr); break; default: return 0; } } else { r = ssh_packet_read_poll1(ssh, typep); switch (*typep) { case SSH_MSG_NONE: return SSH_MSG_NONE; case SSH_MSG_IGNORE: break; case SSH_MSG_DEBUG: if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) return r; debug("Remote: %.900s", msg); free(msg); break; case SSH_MSG_DISCONNECT: if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) return r; error("Received disconnect from %s port %d: " "%.400s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), msg); free(msg); return SSH_ERR_DISCONNECTED; default: DBG(debug("received packet type %d", *typep)); return 0; } } } } /* * Buffers the given amount of input characters. This is intended to be used * together with packet_read_poll. */ int ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) { struct session_state *state = ssh->state; int r; if (state->packet_discard) { state->keep_alive_timeouts = 0; /* ?? */ if (len >= state->packet_discard) { if ((r = ssh_packet_stop_discard(ssh)) != 0) return r; } state->packet_discard -= len; return 0; } if ((r = sshbuf_put(ssh->state->input, buf, len)) != 0) return r; return 0; } int ssh_packet_remaining(struct ssh *ssh) { return sshbuf_len(ssh->state->incoming_packet); } /* * Sends a diagnostic message from the server to the client. This message * can be sent at any time (but not while constructing another message). The * message is printed immediately, but only if the client is being executed * in verbose mode. These messages are primarily intended to ease debugging * authentication problems. The length of the formatted message must not * exceed 1024 bytes. This will automatically call ssh_packet_write_wait. */ void ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) { char buf[1024]; va_list args; int r; if (compat20 && (ssh->compat & SSH_BUG_DEBUG)) return; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (compat20) { if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ (r = sshpkt_put_cstring(ssh, buf)) != 0 || (r = sshpkt_put_cstring(ssh, "")) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } else { if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 || (r = sshpkt_put_cstring(ssh, buf)) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } if ((r = ssh_packet_write_wait(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); } /* * Pretty-print connection-terminating errors and exit. */ void sshpkt_fatal(struct ssh *ssh, const char *tag, int r) { switch (r) { case SSH_ERR_CONN_CLOSED: logit("Connection closed by %.200s port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_CONN_TIMEOUT: logit("Connection %s %.200s port %d timed out", ssh->state->server_side ? "from" : "to", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_DISCONNECTED: logit("Disconnected from %.200s port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_SYSTEM_ERROR: if (errno == ECONNRESET) { logit("Connection reset by %.200s port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); } /* FALLTHROUGH */ case SSH_ERR_NO_CIPHER_ALG_MATCH: case SSH_ERR_NO_MAC_ALG_MATCH: case SSH_ERR_NO_COMPRESS_ALG_MATCH: case SSH_ERR_NO_KEX_ALG_MATCH: case SSH_ERR_NO_HOSTKEY_ALG_MATCH: if (ssh && ssh->kex && ssh->kex->failed_choice) { fatal("Unable to negotiate with %.200s port %d: %s. " "Their offer: %s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r), ssh->kex->failed_choice); } /* FALLTHROUGH */ default: fatal("%s%sConnection %s %.200s port %d: %s", tag != NULL ? tag : "", tag != NULL ? ": " : "", ssh->state->server_side ? "from" : "to", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r)); } } /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message * should not contain a newline. The length of the formatted message must * not exceed 1024 bytes. */ void ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) { char buf[1024]; va_list args; static int disconnecting = 0; int r; if (disconnecting) /* Guard against recursive invocations. */ fatal("packet_disconnect called recursively."); disconnecting = 1; /* * Format the message. Note that the caller must make sure the * message is of limited size. */ va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); /* Display the error locally */ logit("Disconnecting: %.100s", buf); /* * Send the disconnect message to the other side, and wait * for it to get sent. */ if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0) sshpkt_fatal(ssh, __func__, r); if ((r = ssh_packet_write_wait(ssh)) != 0) sshpkt_fatal(ssh, __func__, r); /* Close the connection. */ ssh_packet_close(ssh); cleanup_exit(255); } /* * Checks if there is any buffered output, and tries to write some of * the output. */ int ssh_packet_write_poll(struct ssh *ssh) { struct session_state *state = ssh->state; int len = sshbuf_len(state->output); int r; if (len > 0) { len = write(state->connection_out, sshbuf_ptr(state->output), len); if (len == -1) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return 0; return SSH_ERR_SYSTEM_ERROR; } if (len == 0) return SSH_ERR_CONN_CLOSED; if ((r = sshbuf_consume(state->output, len)) != 0) return r; } return 0; } /* * Calls packet_write_poll repeatedly until all pending output data has been * written. */ int ssh_packet_write_wait(struct ssh *ssh) { fd_set *setp; int ret, r, ms_remain = 0; struct timeval start, timeout, *timeoutp = NULL; struct session_state *state = ssh->state; setp = calloc(howmany(state->connection_out + 1, NFDBITS), sizeof(fd_mask)); if (setp == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = ssh_packet_write_poll(ssh)) != 0) { free(setp); return r; } while (ssh_packet_have_data_to_write(ssh)) { memset(setp, 0, howmany(state->connection_out + 1, NFDBITS) * sizeof(fd_mask)); FD_SET(state->connection_out, setp); if (state->packet_timeout_ms > 0) { ms_remain = state->packet_timeout_ms; timeoutp = &timeout; } for (;;) { if (state->packet_timeout_ms != -1) { ms_to_timeval(&timeout, ms_remain); gettimeofday(&start, NULL); } if ((ret = select(state->connection_out + 1, NULL, setp, NULL, timeoutp)) >= 0) break; if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) break; if (state->packet_timeout_ms == -1) continue; ms_subtract_diff(&start, &ms_remain); if (ms_remain <= 0) { ret = 0; break; } } if (ret == 0) { free(setp); return SSH_ERR_CONN_TIMEOUT; } if ((r = ssh_packet_write_poll(ssh)) != 0) { free(setp); return r; } } free(setp); return 0; } /* Returns true if there is buffered data to write to the connection. */ int ssh_packet_have_data_to_write(struct ssh *ssh) { return sshbuf_len(ssh->state->output) != 0; } /* Returns true if there is not too much data to write to the connection. */ int ssh_packet_not_very_much_data_to_write(struct ssh *ssh) { if (ssh->state->interactive_mode) return sshbuf_len(ssh->state->output) < 16384; else return sshbuf_len(ssh->state->output) < 128 * 1024; } void ssh_packet_set_tos(struct ssh *ssh, int tos) { #ifndef IP_TOS_IS_BROKEN if (!ssh_packet_connection_is_on_socket(ssh)) return; switch (ssh_packet_connection_af(ssh)) { # ifdef IP_TOS case AF_INET: debug3("%s: set IP_TOS 0x%02x", __func__, tos); if (setsockopt(ssh->state->connection_in, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) error("setsockopt IP_TOS %d: %.100s:", tos, strerror(errno)); break; # endif /* IP_TOS */ # ifdef IPV6_TCLASS case AF_INET6: debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos); if (setsockopt(ssh->state->connection_in, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) error("setsockopt IPV6_TCLASS %d: %.100s:", tos, strerror(errno)); break; # endif /* IPV6_TCLASS */ } #endif /* IP_TOS_IS_BROKEN */ } /* Informs that the current session is interactive. Sets IP flags for that. */ void ssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive, int qos_bulk) { struct session_state *state = ssh->state; if (state->set_interactive_called) return; state->set_interactive_called = 1; /* Record that we are in interactive mode. */ state->interactive_mode = interactive; /* Only set socket options if using a socket. */ if (!ssh_packet_connection_is_on_socket(ssh)) return; set_nodelay(state->connection_in); ssh_packet_set_tos(ssh, interactive ? qos_interactive : qos_bulk); } /* Returns true if the current connection is interactive. */ int ssh_packet_is_interactive(struct ssh *ssh) { return ssh->state->interactive_mode; } int ssh_packet_set_maxsize(struct ssh *ssh, u_int s) { struct session_state *state = ssh->state; if (state->set_maxsize_called) { logit("packet_set_maxsize: called twice: old %d new %d", state->max_packet_size, s); return -1; } if (s < 4 * 1024 || s > 1024 * 1024) { logit("packet_set_maxsize: bad size %d", s); return -1; } state->set_maxsize_called = 1; debug("packet_set_maxsize: setting to %d", s); state->max_packet_size = s; return s; } int ssh_packet_inc_alive_timeouts(struct ssh *ssh) { return ++ssh->state->keep_alive_timeouts; } void ssh_packet_set_alive_timeouts(struct ssh *ssh, int ka) { ssh->state->keep_alive_timeouts = ka; } u_int ssh_packet_get_maxsize(struct ssh *ssh) { return ssh->state->max_packet_size; } /* * 9.2. Ignored Data Message * * byte SSH_MSG_IGNORE * string data * * All implementations MUST understand (and ignore) this message at any * time (after receiving the protocol version). No implementation is * required to send them. This message can be used as an additional * protection measure against advanced traffic analysis techniques. */ void ssh_packet_send_ignore(struct ssh *ssh, int nbytes) { u_int32_t rnd = 0; int r, i; if ((r = sshpkt_start(ssh, compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 || (r = sshpkt_put_u32(ssh, nbytes)) != 0) fatal("%s: %s", __func__, ssh_err(r)); for (i = 0; i < nbytes; i++) { if (i % 4 == 0) rnd = arc4random(); if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0) fatal("%s: %s", __func__, ssh_err(r)); rnd >>= 8; } } void ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) { debug3("rekey after %llu bytes, %d seconds", (unsigned long long)bytes, (int)seconds); ssh->state->rekey_limit = bytes; ssh->state->rekey_interval = seconds; } time_t ssh_packet_get_rekey_timeout(struct ssh *ssh) { time_t seconds; seconds = ssh->state->rekey_time + ssh->state->rekey_interval - monotime(); return (seconds <= 0 ? 1 : seconds); } void ssh_packet_set_server(struct ssh *ssh) { ssh->state->server_side = 1; } void ssh_packet_set_authenticated(struct ssh *ssh) { ssh->state->after_authentication = 1; } void * ssh_packet_get_input(struct ssh *ssh) { return (void *)ssh->state->input; } void * ssh_packet_get_output(struct ssh *ssh) { return (void *)ssh->state->output; } /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) { struct sshcomp *comp; int r, mode; debug("%s: called", __func__); /* This was set in net child, but is not visible in user child */ ssh->state->after_authentication = 1; ssh->state->rekeying = 0; for (mode = 0; mode < MODE_MAX; mode++) { if (ssh->state->newkeys[mode] == NULL) continue; comp = &ssh->state->newkeys[mode]->comp; if (comp && comp->enabled && (r = ssh_packet_init_compression(ssh)) != 0) return r; } return 0; } /* Packet state (de-)serialization for privsep */ /* turn kex into a blob for packet state serialization */ static int kex_to_blob(struct sshbuf *m, struct kex *kex) { int r; if ((r = sshbuf_put_string(m, kex->session_id, kex->session_id_len)) != 0 || (r = sshbuf_put_u32(m, kex->we_need)) != 0 || (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 || (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || (r = sshbuf_put_stringb(m, kex->my)) != 0 || (r = sshbuf_put_stringb(m, kex->peer)) != 0 || (r = sshbuf_put_u32(m, kex->flags)) != 0 || (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 || (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0) return r; return 0; } /* turn key exchange results into a blob for packet state serialization */ static int newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) { struct sshbuf *b; struct sshcipher_ctx *cc; struct sshcomp *comp; struct sshenc *enc; struct sshmac *mac; struct newkeys *newkey; int r; if ((newkey = ssh->state->newkeys[mode]) == NULL) return SSH_ERR_INTERNAL_ERROR; enc = &newkey->enc; mac = &newkey->mac; comp = &newkey->comp; cc = (mode == MODE_OUT) ? &ssh->state->send_context : &ssh->state->receive_context; if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0) return r; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* The cipher struct is constant and shared, you export pointer */ if ((r = sshbuf_put_cstring(b, enc->name)) != 0 || (r = sshbuf_put(b, &enc->cipher, sizeof(enc->cipher))) != 0 || (r = sshbuf_put_u32(b, enc->enabled)) != 0 || (r = sshbuf_put_u32(b, enc->block_size)) != 0 || (r = sshbuf_put_string(b, enc->key, enc->key_len)) != 0 || (r = sshbuf_put_string(b, enc->iv, enc->iv_len)) != 0) goto out; if (cipher_authlen(enc->cipher) == 0) { if ((r = sshbuf_put_cstring(b, mac->name)) != 0 || (r = sshbuf_put_u32(b, mac->enabled)) != 0 || (r = sshbuf_put_string(b, mac->key, mac->key_len)) != 0) goto out; } if ((r = sshbuf_put_u32(b, comp->type)) != 0 || (r = sshbuf_put_u32(b, comp->enabled)) != 0 || (r = sshbuf_put_cstring(b, comp->name)) != 0) goto out; r = sshbuf_put_stringb(m, b); out: sshbuf_free(b); return r; } /* serialize packet state into a blob */ int ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) { struct session_state *state = ssh->state; u_char *p; size_t slen, rlen; int r, ssh1cipher; if (!compat20) { ssh1cipher = cipher_get_number(state->receive_context.cipher); slen = cipher_get_keyiv_len(&state->send_context); rlen = cipher_get_keyiv_len(&state->receive_context); if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || (r = sshbuf_put_u32(m, slen)) != 0 || (r = sshbuf_reserve(m, slen, &p)) != 0 || (r = cipher_get_keyiv(&state->send_context, p, slen)) != 0 || (r = sshbuf_put_u32(m, rlen)) != 0 || (r = sshbuf_reserve(m, rlen, &p)) != 0 || (r = cipher_get_keyiv(&state->receive_context, p, rlen)) != 0) return r; } else { if ((r = kex_to_blob(m, ssh->kex)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 || (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 || (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 || (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 || (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 || (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0) return r; } slen = cipher_get_keycontext(&state->send_context, NULL); rlen = cipher_get_keycontext(&state->receive_context, NULL); if ((r = sshbuf_put_u32(m, slen)) != 0 || (r = sshbuf_reserve(m, slen, &p)) != 0) return r; if (cipher_get_keycontext(&state->send_context, p) != (int)slen) return SSH_ERR_INTERNAL_ERROR; if ((r = sshbuf_put_u32(m, rlen)) != 0 || (r = sshbuf_reserve(m, rlen, &p)) != 0) return r; if (cipher_get_keycontext(&state->receive_context, p) != (int)rlen) return SSH_ERR_INTERNAL_ERROR; if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || (r = sshbuf_put_stringb(m, state->input)) != 0 || (r = sshbuf_put_stringb(m, state->output)) != 0) return r; return 0; } /* restore key exchange results from blob for packet state de-serialization */ static int newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) { struct sshbuf *b = NULL; struct sshcomp *comp; struct sshenc *enc; struct sshmac *mac; struct newkeys *newkey = NULL; size_t keylen, ivlen, maclen; int r; if ((newkey = calloc(1, sizeof(*newkey))) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_froms(m, &b)) != 0) goto out; #ifdef DEBUG_PK sshbuf_dump(b, stderr); #endif enc = &newkey->enc; mac = &newkey->mac; comp = &newkey->comp; if ((r = sshbuf_get_cstring(b, &enc->name, NULL)) != 0 || (r = sshbuf_get(b, &enc->cipher, sizeof(enc->cipher))) != 0 || (r = sshbuf_get_u32(b, (u_int *)&enc->enabled)) != 0 || (r = sshbuf_get_u32(b, &enc->block_size)) != 0 || (r = sshbuf_get_string(b, &enc->key, &keylen)) != 0 || (r = sshbuf_get_string(b, &enc->iv, &ivlen)) != 0) goto out; if (cipher_authlen(enc->cipher) == 0) { if ((r = sshbuf_get_cstring(b, &mac->name, NULL)) != 0) goto out; if ((r = mac_setup(mac, mac->name)) != 0) goto out; if ((r = sshbuf_get_u32(b, (u_int *)&mac->enabled)) != 0 || (r = sshbuf_get_string(b, &mac->key, &maclen)) != 0) goto out; if (maclen > mac->key_len) { r = SSH_ERR_INVALID_FORMAT; goto out; } mac->key_len = maclen; } if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || (r = sshbuf_get_u32(b, (u_int *)&comp->enabled)) != 0 || (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) goto out; if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) { r = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(b) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } enc->key_len = keylen; enc->iv_len = ivlen; ssh->kex->newkeys[mode] = newkey; newkey = NULL; r = 0; out: free(newkey); sshbuf_free(b); return r; } /* restore kex from blob for packet state de-serialization */ static int kex_from_blob(struct sshbuf *m, struct kex **kexp) { struct kex *kex; int r; if ((kex = calloc(1, sizeof(struct kex))) == NULL || (kex->my = sshbuf_new()) == NULL || (kex->peer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 || (r = sshbuf_get_u32(m, &kex->we_need)) != 0 || (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 || (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || (r = sshbuf_get_stringb(m, kex->my)) != 0 || (r = sshbuf_get_stringb(m, kex->peer)) != 0 || (r = sshbuf_get_u32(m, &kex->flags)) != 0 || (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 || (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0) goto out; kex->server = 1; kex->done = 1; r = 0; out: if (r != 0 || kexp == NULL) { if (kex != NULL) { sshbuf_free(kex->my); sshbuf_free(kex->peer); free(kex); } if (kexp != NULL) *kexp = NULL; } else { *kexp = kex; } return r; } /* * Restore packet state from content of blob 'm' (de-serialization). * Note that 'm' will be partially consumed on parsing or any other errors. */ int ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) { struct session_state *state = ssh->state; const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output; size_t ssh1keylen, rlen, slen, ilen, olen; int r; u_int ssh1cipher = 0; if (!compat20) { if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 || (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 || (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 || (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0) return r; if (ssh1cipher > INT_MAX) return SSH_ERR_KEY_UNKNOWN_CIPHER; ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, (int)ssh1cipher); if (cipher_get_keyiv_len(&state->send_context) != (int)slen || cipher_get_keyiv_len(&state->receive_context) != (int)rlen) return SSH_ERR_INVALID_FORMAT; if ((r = cipher_set_keyiv(&state->send_context, ivout)) != 0 || (r = cipher_set_keyiv(&state->receive_context, ivin)) != 0) return r; } else { if ((r = kex_from_blob(m, &ssh->kex)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 || (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 || (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 || (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 || (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 || (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 || (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0) return r; /* * We set the time here so that in post-auth privsep slave we * count from the completion of the authentication. */ state->rekey_time = monotime(); /* XXX ssh_set_newkeys overrides p_read.packets? XXX */ if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 || (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0) return r; } if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) return r; if (cipher_get_keycontext(&state->send_context, NULL) != (int)slen || cipher_get_keycontext(&state->receive_context, NULL) != (int)rlen) return SSH_ERR_INVALID_FORMAT; cipher_set_keycontext(&state->send_context, keyout); cipher_set_keycontext(&state->receive_context, keyin); if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || (r = ssh_packet_set_postauth(ssh)) != 0) return r; sshbuf_reset(state->input); sshbuf_reset(state->output); if ((r = sshbuf_get_string_direct(m, &input, &ilen)) != 0 || (r = sshbuf_get_string_direct(m, &output, &olen)) != 0 || (r = sshbuf_put(state->input, input, ilen)) != 0 || (r = sshbuf_put(state->output, output, olen)) != 0) return r; if (sshbuf_len(m)) return SSH_ERR_INVALID_FORMAT; debug3("%s: done", __func__); return 0; } /* NEW API */ /* put data to the outgoing packet */ int sshpkt_put(struct ssh *ssh, const void *v, size_t len) { return sshbuf_put(ssh->state->outgoing_packet, v, len); } int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b) { return sshbuf_putb(ssh->state->outgoing_packet, b); } int sshpkt_put_u8(struct ssh *ssh, u_char val) { return sshbuf_put_u8(ssh->state->outgoing_packet, val); } int sshpkt_put_u32(struct ssh *ssh, u_int32_t val) { return sshbuf_put_u32(ssh->state->outgoing_packet, val); } int sshpkt_put_u64(struct ssh *ssh, u_int64_t val) { return sshbuf_put_u64(ssh->state->outgoing_packet, val); } int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len) { return sshbuf_put_string(ssh->state->outgoing_packet, v, len); } int sshpkt_put_cstring(struct ssh *ssh, const void *v) { return sshbuf_put_cstring(ssh->state->outgoing_packet, v); } int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v) { return sshbuf_put_stringb(ssh->state->outgoing_packet, v); } #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) { return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); } #endif /* OPENSSL_HAS_ECC */ #ifdef WITH_SSH1 int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v) { return sshbuf_put_bignum1(ssh->state->outgoing_packet, v); } #endif /* WITH_SSH1 */ int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) { return sshbuf_put_bignum2(ssh->state->outgoing_packet, v); } #endif /* WITH_OPENSSL */ /* fetch data from the incoming packet */ int sshpkt_get(struct ssh *ssh, void *valp, size_t len) { return sshbuf_get(ssh->state->incoming_packet, valp, len); } int sshpkt_get_u8(struct ssh *ssh, u_char *valp) { return sshbuf_get_u8(ssh->state->incoming_packet, valp); } int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp) { return sshbuf_get_u32(ssh->state->incoming_packet, valp); } int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp) { return sshbuf_get_u64(ssh->state->incoming_packet, valp); } int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp) { return sshbuf_get_string(ssh->state->incoming_packet, valp, lenp); } int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp) { return sshbuf_get_string_direct(ssh->state->incoming_packet, valp, lenp); } int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) { return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); } #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g) { return sshbuf_get_ec(ssh->state->incoming_packet, v, g); } #endif /* OPENSSL_HAS_ECC */ #ifdef WITH_SSH1 int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v) { return sshbuf_get_bignum1(ssh->state->incoming_packet, v); } #endif /* WITH_SSH1 */ int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) { return sshbuf_get_bignum2(ssh->state->incoming_packet, v); } #endif /* WITH_OPENSSL */ int sshpkt_get_end(struct ssh *ssh) { if (sshbuf_len(ssh->state->incoming_packet) > 0) return SSH_ERR_UNEXPECTED_TRAILING_DATA; return 0; } const u_char * sshpkt_ptr(struct ssh *ssh, size_t *lenp) { if (lenp != NULL) *lenp = sshbuf_len(ssh->state->incoming_packet); return sshbuf_ptr(ssh->state->incoming_packet); } /* start a new packet */ int sshpkt_start(struct ssh *ssh, u_char type) { u_char buf[9]; int len; DBG(debug("packet_start[%d]", type)); len = compat20 ? 6 : 9; memset(buf, 0, len - 1); buf[len - 1] = type; sshbuf_reset(ssh->state->outgoing_packet); return sshbuf_put(ssh->state->outgoing_packet, buf, len); } /* send it */ int sshpkt_send(struct ssh *ssh) { if (compat20) return ssh_packet_send2(ssh); else return ssh_packet_send1(ssh); } int sshpkt_disconnect(struct ssh *ssh, const char *fmt,...) { char buf[1024]; va_list args; int r; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (compat20) { if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || (r = sshpkt_put_cstring(ssh, buf)) != 0 || (r = sshpkt_put_cstring(ssh, "")) != 0 || (r = sshpkt_send(ssh)) != 0) return r; } else { if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 || (r = sshpkt_put_cstring(ssh, buf)) != 0 || (r = sshpkt_send(ssh)) != 0) return r; } return 0; } /* roundup current message to pad bytes */ int sshpkt_add_padding(struct ssh *ssh, u_char pad) { ssh->state->extra_pad = pad; return 0; } openssh-7.2p2/packet.h010064400017500001750000000156621267006270000131040ustar00djmdjm/* $OpenBSD: packet.h,v 1.70 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Interface for the packet protocol functions. * * 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 PACKET_H #define PACKET_H #include #ifdef WITH_OPENSSL # include # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ # define EC_KEY void # define EC_GROUP void # define EC_POINT void # endif /* OPENSSL_HAS_ECC */ #else /* WITH_OPENSSL */ # define BIGNUM void # define EC_KEY void # define EC_GROUP void # define EC_POINT void #endif /* WITH_OPENSSL */ #include #include "openbsd-compat/sys-queue.h" struct kex; struct sshkey; struct sshbuf; struct session_state; /* private session data */ #include "dispatch.h" /* typedef, DISPATCH_MAX */ struct key_entry { TAILQ_ENTRY(key_entry) next; struct sshkey *key; }; struct ssh { /* Session state */ struct session_state *state; /* Key exchange */ struct kex *kex; /* cached remote ip address and port*/ char *remote_ipaddr; int remote_port; /* Dispatcher table */ dispatch_fn *dispatch[DISPATCH_MAX]; /* number of packets to ignore in the dispatcher */ int dispatch_skip_packets; /* datafellows */ int compat; /* Lists for private and public keys */ TAILQ_HEAD(, key_entry) private_keys; TAILQ_HEAD(, key_entry) public_keys; /* APP data */ void *app_data; }; struct ssh *ssh_alloc_session_state(void); struct ssh *ssh_packet_set_connection(struct ssh *, int, int); void ssh_packet_set_timeout(struct ssh *, int, int); int ssh_packet_stop_discard(struct ssh *); int ssh_packet_connection_af(struct ssh *); void ssh_packet_set_nonblocking(struct ssh *); int ssh_packet_get_connection_in(struct ssh *); int ssh_packet_get_connection_out(struct ssh *); void ssh_packet_close(struct ssh *); void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int); int ssh_packet_is_rekeying(struct ssh *); void ssh_packet_set_protocol_flags(struct ssh *, u_int); u_int ssh_packet_get_protocol_flags(struct ssh *); int ssh_packet_start_compression(struct ssh *, int); void ssh_packet_set_tos(struct ssh *, int); void ssh_packet_set_interactive(struct ssh *, int, int, int); int ssh_packet_is_interactive(struct ssh *); void ssh_packet_set_server(struct ssh *); void ssh_packet_set_authenticated(struct ssh *); int ssh_packet_send1(struct ssh *); int ssh_packet_send2_wrapped(struct ssh *); int ssh_packet_send2(struct ssh *); int ssh_packet_read(struct ssh *); int ssh_packet_read_expect(struct ssh *, u_int type); int ssh_packet_read_poll(struct ssh *); int ssh_packet_read_poll1(struct ssh *, u_char *); int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); const void *ssh_packet_get_string_ptr(struct ssh *, u_int *length_ptr); void ssh_packet_disconnect(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))) __attribute__((noreturn)); void ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))); int ssh_set_newkeys(struct ssh *, int mode); void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *); typedef void *(ssh_packet_comp_alloc_func)(void *, u_int, u_int); typedef void (ssh_packet_comp_free_func)(void *, void *); void ssh_packet_set_compress_hooks(struct ssh *, void *, ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *); int ssh_packet_write_poll(struct ssh *); int ssh_packet_write_wait(struct ssh *); int ssh_packet_have_data_to_write(struct ssh *); int ssh_packet_not_very_much_data_to_write(struct ssh *); int ssh_packet_connection_is_on_socket(struct ssh *); int ssh_packet_remaining(struct ssh *); void ssh_packet_send_ignore(struct ssh *, int); void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); void ssh_packet_set_alive_timeouts(struct ssh *, int); int ssh_packet_inc_alive_timeouts(struct ssh *); int ssh_packet_set_maxsize(struct ssh *, u_int); u_int ssh_packet_get_maxsize(struct ssh *); int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); const char *ssh_remote_ipaddr(struct ssh *); int ssh_remote_port(struct ssh *); void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, time_t); time_t ssh_packet_get_rekey_timeout(struct ssh *); void *ssh_packet_get_input(struct ssh *); void *ssh_packet_get_output(struct ssh *); /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); int sshpkt_send(struct ssh *ssh); int sshpkt_disconnect(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))); int sshpkt_add_padding(struct ssh *, u_char); void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); int sshpkt_put(struct ssh *ssh, const void *v, size_t len); int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); int sshpkt_put_u8(struct ssh *ssh, u_char val); int sshpkt_put_u32(struct ssh *ssh, u_int32_t val); int sshpkt_put_u64(struct ssh *ssh, u_int64_t val); int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); int sshpkt_put_cstring(struct ssh *ssh, const void *v); int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v); int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); int sshpkt_get(struct ssh *ssh, void *valp, size_t len); int sshpkt_get_u8(struct ssh *ssh, u_char *valp); int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp); int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v); int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); int sshpkt_get_end(struct ssh *ssh); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); /* OLD API */ extern struct ssh *active_state; #include "opacket.h" #if !defined(WITH_OPENSSL) # undef BIGNUM # undef EC_KEY # undef EC_GROUP # undef EC_POINT #elif !defined(OPENSSL_HAS_ECC) # undef EC_KEY # undef EC_GROUP # undef EC_POINT #endif #endif /* PACKET_H */ openssh-7.2p2/pathnames.h010064400017500001750000000137341267006270000136130ustar00djmdjm/* $OpenBSD: pathnames.h,v 1.24 2013/12/06 13:39:49 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ #define ETCDIR "/etc" #ifndef SSHDIR #define SSHDIR ETCDIR "/ssh" #endif #ifndef _PATH_SSH_PIDDIR #define _PATH_SSH_PIDDIR "/var/run" #endif /* * System-wide file containing host keys of known hosts. This file should be * world-readable. */ #define _PATH_SSH_SYSTEM_HOSTFILE SSHDIR "/ssh_known_hosts" /* backward compat for protocol 2 */ #define _PATH_SSH_SYSTEM_HOSTFILE2 SSHDIR "/ssh_known_hosts2" /* * Of these, ssh_host_key must be readable only by root, whereas ssh_config * should be world-readable. */ #define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config" #define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" #define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key" #define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" #define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" #define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" /* Backwards compatibility */ #define _PATH_DH_PRIMES SSHDIR "/primes" #ifndef _PATH_SSH_PROGRAM #define _PATH_SSH_PROGRAM "/usr/bin/ssh" #endif /* * The process id of the daemon listening for connections is saved here to * make it easier to kill the correct daemon when necessary. */ #define _PATH_SSH_DAEMON_PID_FILE _PATH_SSH_PIDDIR "/sshd.pid" /* * The directory in user's home directory in which the files reside. The * directory should be world-readable (though not all files are). */ #define _PATH_SSH_USER_DIR ".ssh" /* * Per-user file containing host keys of known hosts. This file need not be * readable by anyone except the user him/herself, though this does not * contain anything particularly secret. */ #define _PATH_SSH_USER_HOSTFILE "~/" _PATH_SSH_USER_DIR "/known_hosts" /* backward compat for protocol 2 */ #define _PATH_SSH_USER_HOSTFILE2 "~/" _PATH_SSH_USER_DIR "/known_hosts2" /* * Name of the default file containing client-side authentication key. This * file should only be readable by the user him/herself. */ #define _PATH_SSH_CLIENT_IDENTITY _PATH_SSH_USER_DIR "/identity" #define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" #define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" #define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" #define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" /* * Configuration file in user's home directory. This file need not be * readable by anyone but the user him/herself, but does not contain anything * particularly secret. If the user's home directory resides on an NFS * volume where root is mapped to nobody, this may need to be world-readable. */ #define _PATH_SSH_USER_CONFFILE _PATH_SSH_USER_DIR "/config" /* * File containing a list of those rsa keys that permit logging in as this * user. This file need not be readable by anyone but the user him/herself, * but does not contain anything particularly secret. If the user's home * directory resides on an NFS volume where root is mapped to nobody, this * may need to be world-readable. (This file is read by the daemon which is * running as root.) */ #define _PATH_SSH_USER_PERMITTED_KEYS _PATH_SSH_USER_DIR "/authorized_keys" /* backward compat for protocol v2 */ #define _PATH_SSH_USER_PERMITTED_KEYS2 _PATH_SSH_USER_DIR "/authorized_keys2" /* * Per-user and system-wide ssh "rc" files. These files are executed with * /bin/sh before starting the shell or command if they exist. They will be * passed "proto cookie" as arguments if X11 forwarding with spoofing is in * use. xauth will be run if neither of these exists. */ #define _PATH_SSH_USER_RC _PATH_SSH_USER_DIR "/rc" #define _PATH_SSH_SYSTEM_RC SSHDIR "/sshrc" /* * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. */ #define _PATH_SSH_HOSTS_EQUIV SSHDIR "/shosts.equiv" #define _PATH_RHOSTS_EQUIV "/etc/hosts.equiv" /* * Default location of askpass */ #ifndef _PATH_SSH_ASKPASS_DEFAULT #define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" #endif /* Location of ssh-keysign for hostbased authentication */ #ifndef _PATH_SSH_KEY_SIGN #define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" #endif /* Location of ssh-pkcs11-helper to support keys in tokens */ #ifndef _PATH_SSH_PKCS11_HELPER #define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper" #endif /* xauth for X11 forwarding */ #ifndef _PATH_XAUTH #define _PATH_XAUTH "/usr/X11R6/bin/xauth" #endif /* UNIX domain socket for X11 server; displaynum will replace %u */ #ifndef _PATH_UNIX_X #define _PATH_UNIX_X "/tmp/.X11-unix/X%u" #endif /* for scp */ #ifndef _PATH_CP #define _PATH_CP "cp" #endif /* for sftp */ #ifndef _PATH_SFTP_SERVER #define _PATH_SFTP_SERVER "/usr/libexec/sftp-server" #endif /* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */ #ifndef _PATH_PRIVSEP_CHROOT_DIR #define _PATH_PRIVSEP_CHROOT_DIR "/var/empty" #endif /* for passwd change */ #ifndef _PATH_PASSWD_PROG #define _PATH_PASSWD_PROG "/usr/bin/passwd" #endif #ifndef _PATH_LS #define _PATH_LS "ls" #endif /* path to login program */ #ifndef LOGIN_PROGRAM # ifdef LOGIN_PROGRAM_FALLBACK # define LOGIN_PROGRAM LOGIN_PROGRAM_FALLBACK # else # define LOGIN_PROGRAM "/usr/bin/login" # endif #endif /* LOGIN_PROGRAM */ /* Askpass program define */ #ifndef ASKPASS_PROGRAM #define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" #endif /* ASKPASS_PROGRAM */ openssh-7.2p2/pkcs11.h010064400017500001750000001225761267006270000127420ustar00djmdjm/* $OpenBSD: pkcs11.h,v 1.3 2013/11/26 19:15:09 deraadt Exp $ */ /* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* Please submit changes back to the Scute project at http://www.scute.org/ (or send them to marcus@g10code.com), so that they can be picked up by other projects from there as well. */ /* This file is a modified implementation of the PKCS #11 standard by RSA Security Inc. It is mostly a drop-in replacement, with the following change: This header file does not require any macro definitions by the user (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros for you (if useful, some are missing, let me know if you need more). There is an additional API available that does comply better to the GNU coding standard. It can be switched on by defining CRYPTOKI_GNU before including this header file. For this, the following changes are made to the specification: All structure types are changed to a "struct ck_foo" where CK_FOO is the type name in PKCS #11. All non-structure types are changed to ck_foo_t where CK_FOO is the lowercase version of the type name in PKCS #11. The basic types (CK_ULONG et al.) are removed without substitute. All members of structures are modified in the following way: Type indication prefixes are removed, and underscore characters are inserted before words. Then the result is lowercased. Note that function names are still in the original case, as they need for ABI compatibility. CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use . If CRYPTOKI_COMPAT is defined before including this header file, then none of the API changes above take place, and the API is the one defined by the PKCS #11 standard. */ #ifndef PKCS11_H #define PKCS11_H 1 #if defined(__cplusplus) extern "C" { #endif /* The version of cryptoki we implement. The revision is changed with each modification of this file. If you do not use the "official" version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ #define CRYPTOKI_VERSION_MAJOR 2 #define CRYPTOKI_VERSION_MINOR 20 #define CRYPTOKI_VERSION_REVISION 6 /* Compatibility interface is default, unless CRYPTOKI_GNU is given. */ #ifndef CRYPTOKI_GNU #ifndef CRYPTOKI_COMPAT #define CRYPTOKI_COMPAT 1 #endif #endif /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) /* There is a matching pop below. */ #pragma pack(push, cryptoki, 1) #ifdef CRYPTOKI_EXPORTS #define CK_SPEC __declspec(dllexport) #else #define CK_SPEC __declspec(dllimport) #endif #else #define CK_SPEC #endif #ifdef CRYPTOKI_COMPAT /* If we are in compatibility mode, switch all exposed names to the PKCS #11 variant. There are corresponding #undefs below. */ #define ck_flags_t CK_FLAGS #define ck_version _CK_VERSION #define ck_info _CK_INFO #define cryptoki_version cryptokiVersion #define manufacturer_id manufacturerID #define library_description libraryDescription #define library_version libraryVersion #define ck_notification_t CK_NOTIFICATION #define ck_slot_id_t CK_SLOT_ID #define ck_slot_info _CK_SLOT_INFO #define slot_description slotDescription #define hardware_version hardwareVersion #define firmware_version firmwareVersion #define ck_token_info _CK_TOKEN_INFO #define serial_number serialNumber #define max_session_count ulMaxSessionCount #define session_count ulSessionCount #define max_rw_session_count ulMaxRwSessionCount #define rw_session_count ulRwSessionCount #define max_pin_len ulMaxPinLen #define min_pin_len ulMinPinLen #define total_public_memory ulTotalPublicMemory #define free_public_memory ulFreePublicMemory #define total_private_memory ulTotalPrivateMemory #define free_private_memory ulFreePrivateMemory #define utc_time utcTime #define ck_session_handle_t CK_SESSION_HANDLE #define ck_user_type_t CK_USER_TYPE #define ck_state_t CK_STATE #define ck_session_info _CK_SESSION_INFO #define slot_id slotID #define device_error ulDeviceError #define ck_object_handle_t CK_OBJECT_HANDLE #define ck_object_class_t CK_OBJECT_CLASS #define ck_hw_feature_type_t CK_HW_FEATURE_TYPE #define ck_key_type_t CK_KEY_TYPE #define ck_certificate_type_t CK_CERTIFICATE_TYPE #define ck_attribute_type_t CK_ATTRIBUTE_TYPE #define ck_attribute _CK_ATTRIBUTE #define value pValue #define value_len ulValueLen #define ck_date _CK_DATE #define ck_mechanism_type_t CK_MECHANISM_TYPE #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen #define ck_mechanism_info _CK_MECHANISM_INFO #define min_key_size ulMinKeySize #define max_key_size ulMaxKeySize #define ck_rv_t CK_RV #define ck_notify_t CK_NOTIFY #define ck_function_list _CK_FUNCTION_LIST #define ck_createmutex_t CK_CREATEMUTEX #define ck_destroymutex_t CK_DESTROYMUTEX #define ck_lockmutex_t CK_LOCKMUTEX #define ck_unlockmutex_t CK_UNLOCKMUTEX #define ck_c_initialize_args _CK_C_INITIALIZE_ARGS #define create_mutex CreateMutex #define destroy_mutex DestroyMutex #define lock_mutex LockMutex #define unlock_mutex UnlockMutex #define reserved pReserved #endif /* CRYPTOKI_COMPAT */ typedef unsigned long ck_flags_t; struct ck_version { unsigned char major; unsigned char minor; }; struct ck_info { struct ck_version cryptoki_version; unsigned char manufacturer_id[32]; ck_flags_t flags; unsigned char library_description[32]; struct ck_version library_version; }; typedef unsigned long ck_notification_t; #define CKN_SURRENDER (0) typedef unsigned long ck_slot_id_t; struct ck_slot_info { unsigned char slot_description[64]; unsigned char manufacturer_id[32]; ck_flags_t flags; struct ck_version hardware_version; struct ck_version firmware_version; }; #define CKF_TOKEN_PRESENT (1 << 0) #define CKF_REMOVABLE_DEVICE (1 << 1) #define CKF_HW_SLOT (1 << 2) #define CKF_ARRAY_ATTRIBUTE (1 << 30) struct ck_token_info { unsigned char label[32]; unsigned char manufacturer_id[32]; unsigned char model[16]; unsigned char serial_number[16]; ck_flags_t flags; unsigned long max_session_count; unsigned long session_count; unsigned long max_rw_session_count; unsigned long rw_session_count; unsigned long max_pin_len; unsigned long min_pin_len; unsigned long total_public_memory; unsigned long free_public_memory; unsigned long total_private_memory; unsigned long free_private_memory; struct ck_version hardware_version; struct ck_version firmware_version; unsigned char utc_time[16]; }; #define CKF_RNG (1 << 0) #define CKF_WRITE_PROTECTED (1 << 1) #define CKF_LOGIN_REQUIRED (1 << 2) #define CKF_USER_PIN_INITIALIZED (1 << 3) #define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5) #define CKF_CLOCK_ON_TOKEN (1 << 6) #define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8) #define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9) #define CKF_TOKEN_INITIALIZED (1 << 10) #define CKF_SECONDARY_AUTHENTICATION (1 << 11) #define CKF_USER_PIN_COUNT_LOW (1 << 16) #define CKF_USER_PIN_FINAL_TRY (1 << 17) #define CKF_USER_PIN_LOCKED (1 << 18) #define CKF_USER_PIN_TO_BE_CHANGED (1 << 19) #define CKF_SO_PIN_COUNT_LOW (1 << 20) #define CKF_SO_PIN_FINAL_TRY (1 << 21) #define CKF_SO_PIN_LOCKED (1 << 22) #define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) #define CK_EFFECTIVELY_INFINITE (0) typedef unsigned long ck_session_handle_t; #define CK_INVALID_HANDLE (0) typedef unsigned long ck_user_type_t; #define CKU_SO (0) #define CKU_USER (1) #define CKU_CONTEXT_SPECIFIC (2) typedef unsigned long ck_state_t; #define CKS_RO_PUBLIC_SESSION (0) #define CKS_RO_USER_FUNCTIONS (1) #define CKS_RW_PUBLIC_SESSION (2) #define CKS_RW_USER_FUNCTIONS (3) #define CKS_RW_SO_FUNCTIONS (4) struct ck_session_info { ck_slot_id_t slot_id; ck_state_t state; ck_flags_t flags; unsigned long device_error; }; #define CKF_RW_SESSION (1 << 1) #define CKF_SERIAL_SESSION (1 << 2) typedef unsigned long ck_object_handle_t; typedef unsigned long ck_object_class_t; #define CKO_DATA (0) #define CKO_CERTIFICATE (1) #define CKO_PUBLIC_KEY (2) #define CKO_PRIVATE_KEY (3) #define CKO_SECRET_KEY (4) #define CKO_HW_FEATURE (5) #define CKO_DOMAIN_PARAMETERS (6) #define CKO_MECHANISM (7) #define CKO_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_hw_feature_type_t; #define CKH_MONOTONIC_COUNTER (1) #define CKH_CLOCK (2) #define CKH_USER_INTERFACE (3) #define CKH_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_key_type_t; #define CKK_RSA (0) #define CKK_DSA (1) #define CKK_DH (2) #define CKK_ECDSA (3) #define CKK_EC (3) #define CKK_X9_42_DH (4) #define CKK_KEA (5) #define CKK_GENERIC_SECRET (0x10) #define CKK_RC2 (0x11) #define CKK_RC4 (0x12) #define CKK_DES (0x13) #define CKK_DES2 (0x14) #define CKK_DES3 (0x15) #define CKK_CAST (0x16) #define CKK_CAST3 (0x17) #define CKK_CAST128 (0x18) #define CKK_RC5 (0x19) #define CKK_IDEA (0x1a) #define CKK_SKIPJACK (0x1b) #define CKK_BATON (0x1c) #define CKK_JUNIPER (0x1d) #define CKK_CDMF (0x1e) #define CKK_AES (0x1f) #define CKK_BLOWFISH (0x20) #define CKK_TWOFISH (0x21) #define CKK_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_certificate_type_t; #define CKC_X_509 (0) #define CKC_X_509_ATTR_CERT (1) #define CKC_WTLS (2) #define CKC_VENDOR_DEFINED (1U << 31) typedef unsigned long ck_attribute_type_t; #define CKA_CLASS (0) #define CKA_TOKEN (1) #define CKA_PRIVATE (2) #define CKA_LABEL (3) #define CKA_APPLICATION (0x10) #define CKA_VALUE (0x11) #define CKA_OBJECT_ID (0x12) #define CKA_CERTIFICATE_TYPE (0x80) #define CKA_ISSUER (0x81) #define CKA_SERIAL_NUMBER (0x82) #define CKA_AC_ISSUER (0x83) #define CKA_OWNER (0x84) #define CKA_ATTR_TYPES (0x85) #define CKA_TRUSTED (0x86) #define CKA_CERTIFICATE_CATEGORY (0x87) #define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88) #define CKA_URL (0x89) #define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a) #define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b) #define CKA_CHECK_VALUE (0x90) #define CKA_KEY_TYPE (0x100) #define CKA_SUBJECT (0x101) #define CKA_ID (0x102) #define CKA_SENSITIVE (0x103) #define CKA_ENCRYPT (0x104) #define CKA_DECRYPT (0x105) #define CKA_WRAP (0x106) #define CKA_UNWRAP (0x107) #define CKA_SIGN (0x108) #define CKA_SIGN_RECOVER (0x109) #define CKA_VERIFY (0x10a) #define CKA_VERIFY_RECOVER (0x10b) #define CKA_DERIVE (0x10c) #define CKA_START_DATE (0x110) #define CKA_END_DATE (0x111) #define CKA_MODULUS (0x120) #define CKA_MODULUS_BITS (0x121) #define CKA_PUBLIC_EXPONENT (0x122) #define CKA_PRIVATE_EXPONENT (0x123) #define CKA_PRIME_1 (0x124) #define CKA_PRIME_2 (0x125) #define CKA_EXPONENT_1 (0x126) #define CKA_EXPONENT_2 (0x127) #define CKA_COEFFICIENT (0x128) #define CKA_PRIME (0x130) #define CKA_SUBPRIME (0x131) #define CKA_BASE (0x132) #define CKA_PRIME_BITS (0x133) #define CKA_SUB_PRIME_BITS (0x134) #define CKA_VALUE_BITS (0x160) #define CKA_VALUE_LEN (0x161) #define CKA_EXTRACTABLE (0x162) #define CKA_LOCAL (0x163) #define CKA_NEVER_EXTRACTABLE (0x164) #define CKA_ALWAYS_SENSITIVE (0x165) #define CKA_KEY_GEN_MECHANISM (0x166) #define CKA_MODIFIABLE (0x170) #define CKA_ECDSA_PARAMS (0x180) #define CKA_EC_PARAMS (0x180) #define CKA_EC_POINT (0x181) #define CKA_SECONDARY_AUTH (0x200) #define CKA_AUTH_PIN_FLAGS (0x201) #define CKA_ALWAYS_AUTHENTICATE (0x202) #define CKA_WRAP_WITH_TRUSTED (0x210) #define CKA_HW_FEATURE_TYPE (0x300) #define CKA_RESET_ON_INIT (0x301) #define CKA_HAS_RESET (0x302) #define CKA_PIXEL_X (0x400) #define CKA_PIXEL_Y (0x401) #define CKA_RESOLUTION (0x402) #define CKA_CHAR_ROWS (0x403) #define CKA_CHAR_COLUMNS (0x404) #define CKA_COLOR (0x405) #define CKA_BITS_PER_PIXEL (0x406) #define CKA_CHAR_SETS (0x480) #define CKA_ENCODING_METHODS (0x481) #define CKA_MIME_TYPES (0x482) #define CKA_MECHANISM_TYPE (0x500) #define CKA_REQUIRED_CMS_ATTRIBUTES (0x501) #define CKA_DEFAULT_CMS_ATTRIBUTES (0x502) #define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503) #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) #define CKA_VENDOR_DEFINED (1U << 31) struct ck_attribute { ck_attribute_type_t type; void *value; unsigned long value_len; }; struct ck_date { unsigned char year[4]; unsigned char month[2]; unsigned char day[2]; }; typedef unsigned long ck_mechanism_type_t; #define CKM_RSA_PKCS_KEY_PAIR_GEN (0) #define CKM_RSA_PKCS (1) #define CKM_RSA_9796 (2) #define CKM_RSA_X_509 (3) #define CKM_MD2_RSA_PKCS (4) #define CKM_MD5_RSA_PKCS (5) #define CKM_SHA1_RSA_PKCS (6) #define CKM_RIPEMD128_RSA_PKCS (7) #define CKM_RIPEMD160_RSA_PKCS (8) #define CKM_RSA_PKCS_OAEP (9) #define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa) #define CKM_RSA_X9_31 (0xb) #define CKM_SHA1_RSA_X9_31 (0xc) #define CKM_RSA_PKCS_PSS (0xd) #define CKM_SHA1_RSA_PKCS_PSS (0xe) #define CKM_DSA_KEY_PAIR_GEN (0x10) #define CKM_DSA (0x11) #define CKM_DSA_SHA1 (0x12) #define CKM_DH_PKCS_KEY_PAIR_GEN (0x20) #define CKM_DH_PKCS_DERIVE (0x21) #define CKM_X9_42_DH_KEY_PAIR_GEN (0x30) #define CKM_X9_42_DH_DERIVE (0x31) #define CKM_X9_42_DH_HYBRID_DERIVE (0x32) #define CKM_X9_42_MQV_DERIVE (0x33) #define CKM_SHA256_RSA_PKCS (0x40) #define CKM_SHA384_RSA_PKCS (0x41) #define CKM_SHA512_RSA_PKCS (0x42) #define CKM_SHA256_RSA_PKCS_PSS (0x43) #define CKM_SHA384_RSA_PKCS_PSS (0x44) #define CKM_SHA512_RSA_PKCS_PSS (0x45) #define CKM_RC2_KEY_GEN (0x100) #define CKM_RC2_ECB (0x101) #define CKM_RC2_CBC (0x102) #define CKM_RC2_MAC (0x103) #define CKM_RC2_MAC_GENERAL (0x104) #define CKM_RC2_CBC_PAD (0x105) #define CKM_RC4_KEY_GEN (0x110) #define CKM_RC4 (0x111) #define CKM_DES_KEY_GEN (0x120) #define CKM_DES_ECB (0x121) #define CKM_DES_CBC (0x122) #define CKM_DES_MAC (0x123) #define CKM_DES_MAC_GENERAL (0x124) #define CKM_DES_CBC_PAD (0x125) #define CKM_DES2_KEY_GEN (0x130) #define CKM_DES3_KEY_GEN (0x131) #define CKM_DES3_ECB (0x132) #define CKM_DES3_CBC (0x133) #define CKM_DES3_MAC (0x134) #define CKM_DES3_MAC_GENERAL (0x135) #define CKM_DES3_CBC_PAD (0x136) #define CKM_CDMF_KEY_GEN (0x140) #define CKM_CDMF_ECB (0x141) #define CKM_CDMF_CBC (0x142) #define CKM_CDMF_MAC (0x143) #define CKM_CDMF_MAC_GENERAL (0x144) #define CKM_CDMF_CBC_PAD (0x145) #define CKM_MD2 (0x200) #define CKM_MD2_HMAC (0x201) #define CKM_MD2_HMAC_GENERAL (0x202) #define CKM_MD5 (0x210) #define CKM_MD5_HMAC (0x211) #define CKM_MD5_HMAC_GENERAL (0x212) #define CKM_SHA_1 (0x220) #define CKM_SHA_1_HMAC (0x221) #define CKM_SHA_1_HMAC_GENERAL (0x222) #define CKM_RIPEMD128 (0x230) #define CKM_RIPEMD128_HMAC (0x231) #define CKM_RIPEMD128_HMAC_GENERAL (0x232) #define CKM_RIPEMD160 (0x240) #define CKM_RIPEMD160_HMAC (0x241) #define CKM_RIPEMD160_HMAC_GENERAL (0x242) #define CKM_SHA256 (0x250) #define CKM_SHA256_HMAC (0x251) #define CKM_SHA256_HMAC_GENERAL (0x252) #define CKM_SHA384 (0x260) #define CKM_SHA384_HMAC (0x261) #define CKM_SHA384_HMAC_GENERAL (0x262) #define CKM_SHA512 (0x270) #define CKM_SHA512_HMAC (0x271) #define CKM_SHA512_HMAC_GENERAL (0x272) #define CKM_CAST_KEY_GEN (0x300) #define CKM_CAST_ECB (0x301) #define CKM_CAST_CBC (0x302) #define CKM_CAST_MAC (0x303) #define CKM_CAST_MAC_GENERAL (0x304) #define CKM_CAST_CBC_PAD (0x305) #define CKM_CAST3_KEY_GEN (0x310) #define CKM_CAST3_ECB (0x311) #define CKM_CAST3_CBC (0x312) #define CKM_CAST3_MAC (0x313) #define CKM_CAST3_MAC_GENERAL (0x314) #define CKM_CAST3_CBC_PAD (0x315) #define CKM_CAST5_KEY_GEN (0x320) #define CKM_CAST128_KEY_GEN (0x320) #define CKM_CAST5_ECB (0x321) #define CKM_CAST128_ECB (0x321) #define CKM_CAST5_CBC (0x322) #define CKM_CAST128_CBC (0x322) #define CKM_CAST5_MAC (0x323) #define CKM_CAST128_MAC (0x323) #define CKM_CAST5_MAC_GENERAL (0x324) #define CKM_CAST128_MAC_GENERAL (0x324) #define CKM_CAST5_CBC_PAD (0x325) #define CKM_CAST128_CBC_PAD (0x325) #define CKM_RC5_KEY_GEN (0x330) #define CKM_RC5_ECB (0x331) #define CKM_RC5_CBC (0x332) #define CKM_RC5_MAC (0x333) #define CKM_RC5_MAC_GENERAL (0x334) #define CKM_RC5_CBC_PAD (0x335) #define CKM_IDEA_KEY_GEN (0x340) #define CKM_IDEA_ECB (0x341) #define CKM_IDEA_CBC (0x342) #define CKM_IDEA_MAC (0x343) #define CKM_IDEA_MAC_GENERAL (0x344) #define CKM_IDEA_CBC_PAD (0x345) #define CKM_GENERIC_SECRET_KEY_GEN (0x350) #define CKM_CONCATENATE_BASE_AND_KEY (0x360) #define CKM_CONCATENATE_BASE_AND_DATA (0x362) #define CKM_CONCATENATE_DATA_AND_BASE (0x363) #define CKM_XOR_BASE_AND_DATA (0x364) #define CKM_EXTRACT_KEY_FROM_KEY (0x365) #define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370) #define CKM_SSL3_MASTER_KEY_DERIVE (0x371) #define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372) #define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373) #define CKM_TLS_PRE_MASTER_KEY_GEN (0x374) #define CKM_TLS_MASTER_KEY_DERIVE (0x375) #define CKM_TLS_KEY_AND_MAC_DERIVE (0x376) #define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377) #define CKM_SSL3_MD5_MAC (0x380) #define CKM_SSL3_SHA1_MAC (0x381) #define CKM_MD5_KEY_DERIVATION (0x390) #define CKM_MD2_KEY_DERIVATION (0x391) #define CKM_SHA1_KEY_DERIVATION (0x392) #define CKM_PBE_MD2_DES_CBC (0x3a0) #define CKM_PBE_MD5_DES_CBC (0x3a1) #define CKM_PBE_MD5_CAST_CBC (0x3a2) #define CKM_PBE_MD5_CAST3_CBC (0x3a3) #define CKM_PBE_MD5_CAST5_CBC (0x3a4) #define CKM_PBE_MD5_CAST128_CBC (0x3a4) #define CKM_PBE_SHA1_CAST5_CBC (0x3a5) #define CKM_PBE_SHA1_CAST128_CBC (0x3a5) #define CKM_PBE_SHA1_RC4_128 (0x3a6) #define CKM_PBE_SHA1_RC4_40 (0x3a7) #define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8) #define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9) #define CKM_PBE_SHA1_RC2_128_CBC (0x3aa) #define CKM_PBE_SHA1_RC2_40_CBC (0x3ab) #define CKM_PKCS5_PBKD2 (0x3b0) #define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0) #define CKM_KEY_WRAP_LYNKS (0x400) #define CKM_KEY_WRAP_SET_OAEP (0x401) #define CKM_SKIPJACK_KEY_GEN (0x1000) #define CKM_SKIPJACK_ECB64 (0x1001) #define CKM_SKIPJACK_CBC64 (0x1002) #define CKM_SKIPJACK_OFB64 (0x1003) #define CKM_SKIPJACK_CFB64 (0x1004) #define CKM_SKIPJACK_CFB32 (0x1005) #define CKM_SKIPJACK_CFB16 (0x1006) #define CKM_SKIPJACK_CFB8 (0x1007) #define CKM_SKIPJACK_WRAP (0x1008) #define CKM_SKIPJACK_PRIVATE_WRAP (0x1009) #define CKM_SKIPJACK_RELAYX (0x100a) #define CKM_KEA_KEY_PAIR_GEN (0x1010) #define CKM_KEA_KEY_DERIVE (0x1011) #define CKM_FORTEZZA_TIMESTAMP (0x1020) #define CKM_BATON_KEY_GEN (0x1030) #define CKM_BATON_ECB128 (0x1031) #define CKM_BATON_ECB96 (0x1032) #define CKM_BATON_CBC128 (0x1033) #define CKM_BATON_COUNTER (0x1034) #define CKM_BATON_SHUFFLE (0x1035) #define CKM_BATON_WRAP (0x1036) #define CKM_ECDSA_KEY_PAIR_GEN (0x1040) #define CKM_EC_KEY_PAIR_GEN (0x1040) #define CKM_ECDSA (0x1041) #define CKM_ECDSA_SHA1 (0x1042) #define CKM_ECDH1_DERIVE (0x1050) #define CKM_ECDH1_COFACTOR_DERIVE (0x1051) #define CKM_ECMQV_DERIVE (0x1052) #define CKM_JUNIPER_KEY_GEN (0x1060) #define CKM_JUNIPER_ECB128 (0x1061) #define CKM_JUNIPER_CBC128 (0x1062) #define CKM_JUNIPER_COUNTER (0x1063) #define CKM_JUNIPER_SHUFFLE (0x1064) #define CKM_JUNIPER_WRAP (0x1065) #define CKM_FASTHASH (0x1070) #define CKM_AES_KEY_GEN (0x1080) #define CKM_AES_ECB (0x1081) #define CKM_AES_CBC (0x1082) #define CKM_AES_MAC (0x1083) #define CKM_AES_MAC_GENERAL (0x1084) #define CKM_AES_CBC_PAD (0x1085) #define CKM_DSA_PARAMETER_GEN (0x2000) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002) #define CKM_VENDOR_DEFINED (1U << 31) struct ck_mechanism { ck_mechanism_type_t mechanism; void *parameter; unsigned long parameter_len; }; struct ck_mechanism_info { unsigned long min_key_size; unsigned long max_key_size; ck_flags_t flags; }; #define CKF_HW (1 << 0) #define CKF_ENCRYPT (1 << 8) #define CKF_DECRYPT (1 << 9) #define CKF_DIGEST (1 << 10) #define CKF_SIGN (1 << 11) #define CKF_SIGN_RECOVER (1 << 12) #define CKF_VERIFY (1 << 13) #define CKF_VERIFY_RECOVER (1 << 14) #define CKF_GENERATE (1 << 15) #define CKF_GENERATE_KEY_PAIR (1 << 16) #define CKF_WRAP (1 << 17) #define CKF_UNWRAP (1 << 18) #define CKF_DERIVE (1 << 19) #define CKF_EXTENSION (1U << 31) /* Flags for C_WaitForSlotEvent. */ #define CKF_DONT_BLOCK (1) typedef unsigned long ck_rv_t; typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, ck_notification_t event, void *application); /* Forward reference. */ struct ck_function_list; #define _CK_DECLARE_FUNCTION(name, args) \ typedef ck_rv_t (*CK_ ## name) args; \ ck_rv_t CK_SPEC name args _CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); _CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); _CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); _CK_DECLARE_FUNCTION (C_GetFunctionList, (struct ck_function_list **function_list)); _CK_DECLARE_FUNCTION (C_GetSlotList, (unsigned char token_present, ck_slot_id_t *slot_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetSlotInfo, (ck_slot_id_t slot_id, struct ck_slot_info *info)); _CK_DECLARE_FUNCTION (C_GetTokenInfo, (ck_slot_id_t slot_id, struct ck_token_info *info)); _CK_DECLARE_FUNCTION (C_WaitForSlotEvent, (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); _CK_DECLARE_FUNCTION (C_GetMechanismList, (ck_slot_id_t slot_id, ck_mechanism_type_t *mechanism_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetMechanismInfo, (ck_slot_id_t slot_id, ck_mechanism_type_t type, struct ck_mechanism_info *info)); _CK_DECLARE_FUNCTION (C_InitToken, (ck_slot_id_t slot_id, unsigned char *pin, unsigned long pin_len, unsigned char *label)); _CK_DECLARE_FUNCTION (C_InitPIN, (ck_session_handle_t session, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_SetPIN, (ck_session_handle_t session, unsigned char *old_pin, unsigned long old_len, unsigned char *new_pin, unsigned long new_len)); _CK_DECLARE_FUNCTION (C_OpenSession, (ck_slot_id_t slot_id, ck_flags_t flags, void *application, ck_notify_t notify, ck_session_handle_t *session)); _CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); _CK_DECLARE_FUNCTION (C_GetSessionInfo, (ck_session_handle_t session, struct ck_session_info *info)); _CK_DECLARE_FUNCTION (C_GetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long *operation_state_len)); _CK_DECLARE_FUNCTION (C_SetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, ck_object_handle_t authentiation_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CreateObject, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *object)); _CK_DECLARE_FUNCTION (C_CopyObject, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *new_object)); _CK_DECLARE_FUNCTION (C_DestroyObject, (ck_session_handle_t session, ck_object_handle_t object)); _CK_DECLARE_FUNCTION (C_GetObjectSize, (ck_session_handle_t session, ck_object_handle_t object, unsigned long *size)); _CK_DECLARE_FUNCTION (C_GetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_SetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjectsInit, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjects, (ck_session_handle_t session, ck_object_handle_t *object, unsigned long max_object_count, unsigned long *object_count)); _CK_DECLARE_FUNCTION (C_FindObjectsFinal, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_EncryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Encrypt, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *encrypted_data, unsigned long *encrypted_data_len)); _CK_DECLARE_FUNCTION (C_EncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_EncryptFinal, (ck_session_handle_t session, unsigned char *last_encrypted_part, unsigned long *last_encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Decrypt, (ck_session_handle_t session, unsigned char *encrypted_data, unsigned long encrypted_data_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DecryptUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_DecryptFinal, (ck_session_handle_t session, unsigned char *last_part, unsigned long *last_part_len)); _CK_DECLARE_FUNCTION (C_DigestInit, (ck_session_handle_t session, struct ck_mechanism *mechanism)); _CK_DECLARE_FUNCTION (C_Digest, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_DigestUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_DigestKey, (ck_session_handle_t session, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_DigestFinal, (ck_session_handle_t session, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_SignInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Sign, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_SignFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_SignRecover, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_VerifyInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Verify, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_VerifyFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_VerifyRecover, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_SignEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_GenerateKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_GenerateKeyPair, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *public_key_template, unsigned long public_key_attribute_count, struct ck_attribute *private_key_template, unsigned long private_key_attribute_count, ck_object_handle_t *public_key, ck_object_handle_t *private_key)); _CK_DECLARE_FUNCTION (C_WrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t wrapping_key, ck_object_handle_t key, unsigned char *wrapped_key, unsigned long *wrapped_key_len)); _CK_DECLARE_FUNCTION (C_UnwrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t unwrapping_key, unsigned char *wrapped_key, unsigned long wrapped_key_len, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_DeriveKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t base_key, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_SeedRandom, (ck_session_handle_t session, unsigned char *seed, unsigned long seed_len)); _CK_DECLARE_FUNCTION (C_GenerateRandom, (ck_session_handle_t session, unsigned char *random_data, unsigned long random_len)); _CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); struct ck_function_list { struct ck_version version; CK_C_Initialize C_Initialize; CK_C_Finalize C_Finalize; CK_C_GetInfo C_GetInfo; CK_C_GetFunctionList C_GetFunctionList; CK_C_GetSlotList C_GetSlotList; CK_C_GetSlotInfo C_GetSlotInfo; CK_C_GetTokenInfo C_GetTokenInfo; CK_C_GetMechanismList C_GetMechanismList; CK_C_GetMechanismInfo C_GetMechanismInfo; CK_C_InitToken C_InitToken; CK_C_InitPIN C_InitPIN; CK_C_SetPIN C_SetPIN; CK_C_OpenSession C_OpenSession; CK_C_CloseSession C_CloseSession; CK_C_CloseAllSessions C_CloseAllSessions; CK_C_GetSessionInfo C_GetSessionInfo; CK_C_GetOperationState C_GetOperationState; CK_C_SetOperationState C_SetOperationState; CK_C_Login C_Login; CK_C_Logout C_Logout; CK_C_CreateObject C_CreateObject; CK_C_CopyObject C_CopyObject; CK_C_DestroyObject C_DestroyObject; CK_C_GetObjectSize C_GetObjectSize; CK_C_GetAttributeValue C_GetAttributeValue; CK_C_SetAttributeValue C_SetAttributeValue; CK_C_FindObjectsInit C_FindObjectsInit; CK_C_FindObjects C_FindObjects; CK_C_FindObjectsFinal C_FindObjectsFinal; CK_C_EncryptInit C_EncryptInit; CK_C_Encrypt C_Encrypt; CK_C_EncryptUpdate C_EncryptUpdate; CK_C_EncryptFinal C_EncryptFinal; CK_C_DecryptInit C_DecryptInit; CK_C_Decrypt C_Decrypt; CK_C_DecryptUpdate C_DecryptUpdate; CK_C_DecryptFinal C_DecryptFinal; CK_C_DigestInit C_DigestInit; CK_C_Digest C_Digest; CK_C_DigestUpdate C_DigestUpdate; CK_C_DigestKey C_DigestKey; CK_C_DigestFinal C_DigestFinal; CK_C_SignInit C_SignInit; CK_C_Sign C_Sign; CK_C_SignUpdate C_SignUpdate; CK_C_SignFinal C_SignFinal; CK_C_SignRecoverInit C_SignRecoverInit; CK_C_SignRecover C_SignRecover; CK_C_VerifyInit C_VerifyInit; CK_C_Verify C_Verify; CK_C_VerifyUpdate C_VerifyUpdate; CK_C_VerifyFinal C_VerifyFinal; CK_C_VerifyRecoverInit C_VerifyRecoverInit; CK_C_VerifyRecover C_VerifyRecover; CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; CK_C_SignEncryptUpdate C_SignEncryptUpdate; CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; CK_C_GenerateKey C_GenerateKey; CK_C_GenerateKeyPair C_GenerateKeyPair; CK_C_WrapKey C_WrapKey; CK_C_UnwrapKey C_UnwrapKey; CK_C_DeriveKey C_DeriveKey; CK_C_SeedRandom C_SeedRandom; CK_C_GenerateRandom C_GenerateRandom; CK_C_GetFunctionStatus C_GetFunctionStatus; CK_C_CancelFunction C_CancelFunction; CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; typedef ck_rv_t (*ck_createmutex_t) (void **mutex); typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); struct ck_c_initialize_args { ck_createmutex_t create_mutex; ck_destroymutex_t destroy_mutex; ck_lockmutex_t lock_mutex; ck_unlockmutex_t unlock_mutex; ck_flags_t flags; void *reserved; }; #define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) #define CKF_OS_LOCKING_OK (1 << 1) #define CKR_OK (0) #define CKR_CANCEL (1) #define CKR_HOST_MEMORY (2) #define CKR_SLOT_ID_INVALID (3) #define CKR_GENERAL_ERROR (5) #define CKR_FUNCTION_FAILED (6) #define CKR_ARGUMENTS_BAD (7) #define CKR_NO_EVENT (8) #define CKR_NEED_TO_CREATE_THREADS (9) #define CKR_CANT_LOCK (0xa) #define CKR_ATTRIBUTE_READ_ONLY (0x10) #define CKR_ATTRIBUTE_SENSITIVE (0x11) #define CKR_ATTRIBUTE_TYPE_INVALID (0x12) #define CKR_ATTRIBUTE_VALUE_INVALID (0x13) #define CKR_DATA_INVALID (0x20) #define CKR_DATA_LEN_RANGE (0x21) #define CKR_DEVICE_ERROR (0x30) #define CKR_DEVICE_MEMORY (0x31) #define CKR_DEVICE_REMOVED (0x32) #define CKR_ENCRYPTED_DATA_INVALID (0x40) #define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41) #define CKR_FUNCTION_CANCELED (0x50) #define CKR_FUNCTION_NOT_PARALLEL (0x51) #define CKR_FUNCTION_NOT_SUPPORTED (0x54) #define CKR_KEY_HANDLE_INVALID (0x60) #define CKR_KEY_SIZE_RANGE (0x62) #define CKR_KEY_TYPE_INCONSISTENT (0x63) #define CKR_KEY_NOT_NEEDED (0x64) #define CKR_KEY_CHANGED (0x65) #define CKR_KEY_NEEDED (0x66) #define CKR_KEY_INDIGESTIBLE (0x67) #define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68) #define CKR_KEY_NOT_WRAPPABLE (0x69) #define CKR_KEY_UNEXTRACTABLE (0x6a) #define CKR_MECHANISM_INVALID (0x70) #define CKR_MECHANISM_PARAM_INVALID (0x71) #define CKR_OBJECT_HANDLE_INVALID (0x82) #define CKR_OPERATION_ACTIVE (0x90) #define CKR_OPERATION_NOT_INITIALIZED (0x91) #define CKR_PIN_INCORRECT (0xa0) #define CKR_PIN_INVALID (0xa1) #define CKR_PIN_LEN_RANGE (0xa2) #define CKR_PIN_EXPIRED (0xa3) #define CKR_PIN_LOCKED (0xa4) #define CKR_SESSION_CLOSED (0xb0) #define CKR_SESSION_COUNT (0xb1) #define CKR_SESSION_HANDLE_INVALID (0xb3) #define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4) #define CKR_SESSION_READ_ONLY (0xb5) #define CKR_SESSION_EXISTS (0xb6) #define CKR_SESSION_READ_ONLY_EXISTS (0xb7) #define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8) #define CKR_SIGNATURE_INVALID (0xc0) #define CKR_SIGNATURE_LEN_RANGE (0xc1) #define CKR_TEMPLATE_INCOMPLETE (0xd0) #define CKR_TEMPLATE_INCONSISTENT (0xd1) #define CKR_TOKEN_NOT_PRESENT (0xe0) #define CKR_TOKEN_NOT_RECOGNIZED (0xe1) #define CKR_TOKEN_WRITE_PROTECTED (0xe2) #define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0) #define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1) #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2) #define CKR_USER_ALREADY_LOGGED_IN (0x100) #define CKR_USER_NOT_LOGGED_IN (0x101) #define CKR_USER_PIN_NOT_INITIALIZED (0x102) #define CKR_USER_TYPE_INVALID (0x103) #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104) #define CKR_USER_TOO_MANY_TYPES (0x105) #define CKR_WRAPPED_KEY_INVALID (0x110) #define CKR_WRAPPED_KEY_LEN_RANGE (0x112) #define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113) #define CKR_WRAPPING_KEY_SIZE_RANGE (0x114) #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115) #define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120) #define CKR_RANDOM_NO_RNG (0x121) #define CKR_DOMAIN_PARAMS_INVALID (0x130) #define CKR_BUFFER_TOO_SMALL (0x150) #define CKR_SAVED_STATE_INVALID (0x160) #define CKR_INFORMATION_SENSITIVE (0x170) #define CKR_STATE_UNSAVEABLE (0x180) #define CKR_CRYPTOKI_NOT_INITIALIZED (0x190) #define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191) #define CKR_MUTEX_BAD (0x1a0) #define CKR_MUTEX_NOT_LOCKED (0x1a1) #define CKR_FUNCTION_REJECTED (0x200) #define CKR_VENDOR_DEFINED (1U << 31) /* Compatibility layer. */ #ifdef CRYPTOKI_COMPAT #undef CK_DEFINE_FUNCTION #define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name /* For NULL. */ #include typedef unsigned char CK_BYTE; typedef unsigned char CK_CHAR; typedef unsigned char CK_UTF8CHAR; typedef unsigned char CK_BBOOL; typedef unsigned long int CK_ULONG; typedef long int CK_LONG; typedef CK_BYTE *CK_BYTE_PTR; typedef CK_CHAR *CK_CHAR_PTR; typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; typedef CK_ULONG *CK_ULONG_PTR; typedef void *CK_VOID_PTR; typedef void **CK_VOID_PTR_PTR; #define CK_FALSE 0 #define CK_TRUE 1 #ifndef CK_DISABLE_TRUE_FALSE #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; typedef struct ck_info CK_INFO; typedef struct ck_info *CK_INFO_PTR; typedef ck_slot_id_t *CK_SLOT_ID_PTR; typedef struct ck_slot_info CK_SLOT_INFO; typedef struct ck_slot_info *CK_SLOT_INFO_PTR; typedef struct ck_token_info CK_TOKEN_INFO; typedef struct ck_token_info *CK_TOKEN_INFO_PTR; typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; typedef struct ck_session_info CK_SESSION_INFO; typedef struct ck_session_info *CK_SESSION_INFO_PTR; typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; typedef struct ck_attribute CK_ATTRIBUTE; typedef struct ck_attribute *CK_ATTRIBUTE_PTR; typedef struct ck_date CK_DATE; typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; typedef struct ck_mechanism_info CK_MECHANISM_INFO; typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; typedef struct ck_function_list CK_FUNCTION_LIST; typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #define NULL_PTR NULL /* Delete the helper macros defined at the top of the file. */ #undef ck_flags_t #undef ck_version #undef ck_info #undef cryptoki_version #undef manufacturer_id #undef library_description #undef library_version #undef ck_notification_t #undef ck_slot_id_t #undef ck_slot_info #undef slot_description #undef hardware_version #undef firmware_version #undef ck_token_info #undef serial_number #undef max_session_count #undef session_count #undef max_rw_session_count #undef rw_session_count #undef max_pin_len #undef min_pin_len #undef total_public_memory #undef free_public_memory #undef total_private_memory #undef free_private_memory #undef utc_time #undef ck_session_handle_t #undef ck_user_type_t #undef ck_state_t #undef ck_session_info #undef slot_id #undef device_error #undef ck_object_handle_t #undef ck_object_class_t #undef ck_hw_feature_type_t #undef ck_key_type_t #undef ck_certificate_type_t #undef ck_attribute_type_t #undef ck_attribute #undef value #undef value_len #undef ck_date #undef ck_mechanism_type_t #undef ck_mechanism #undef parameter #undef parameter_len #undef ck_mechanism_info #undef min_key_size #undef max_key_size #undef ck_rv_t #undef ck_notify_t #undef ck_function_list #undef ck_createmutex_t #undef ck_destroymutex_t #undef ck_lockmutex_t #undef ck_unlockmutex_t #undef ck_c_initialize_args #undef create_mutex #undef destroy_mutex #undef lock_mutex #undef unlock_mutex #undef reserved #endif /* CRYPTOKI_COMPAT */ /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) #pragma pack(pop, cryptoki) #endif #if defined(__cplusplus) } #endif #endif /* PKCS11_H */ openssh-7.2p2/platform-pledge.c010064400017500001750000000035651267006270000147110ustar00djmdjm/* * Copyright (c) 2015 Joyent, Inc * Author: Alex Wilson * * 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 #include #include #include "platform.h" #include "openbsd-compat/openbsd-compat.h" /* * Drop any fine-grained privileges that are not needed for post-startup * operation of ssh-agent * * Should be as close as possible to pledge("stdio cpath unix id proc exec", ...) */ void platform_pledge_agent(void) { #ifdef USE_SOLARIS_PRIVS /* * Note: Solaris priv dropping is closer to tame() than pledge(), but * we will use what we have. */ solaris_drop_privs_root_pinfo_net(); #endif } /* * Drop any fine-grained privileges that are not needed for post-startup * operation of sftp-server */ void platform_pledge_sftp_server(void) { #ifdef USE_SOLARIS_PRIVS solaris_drop_privs_pinfo_net_fork_exec(); #endif } /* * Drop any fine-grained privileges that are not needed for the post-startup * operation of the SSH client mux * * Should be as close as possible to pledge("stdio proc tty", ...) */ void platform_pledge_mux(void) { #ifdef USE_SOLARIS_PRIVS solaris_drop_privs_root_pinfo_net_exec(); #endif } openssh-7.2p2/platform.c010064400017500001750000000117101267006270000134420ustar00djmdjm/* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #include #include #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.h" #include "key.h" #include "hostfile.h" #include "auth.h" #include "auth-pam.h" #include "platform.h" #include "openbsd-compat/openbsd-compat.h" extern int use_privsep; extern ServerOptions options; void platform_pre_listen(void) { #ifdef LINUX_OOM_ADJUST /* Adjust out-of-memory killer so listening process is not killed */ oom_adjust_setup(); #endif } void platform_pre_fork(void) { #ifdef USE_SOLARIS_PROCESS_CONTRACTS solaris_contract_pre_fork(); #endif } void platform_pre_restart(void) { #ifdef LINUX_OOM_ADJUST oom_adjust_restore(); #endif } void platform_post_fork_parent(pid_t child_pid) { #ifdef USE_SOLARIS_PROCESS_CONTRACTS solaris_contract_post_fork_parent(child_pid); #endif } void platform_post_fork_child(void) { #ifdef USE_SOLARIS_PROCESS_CONTRACTS solaris_contract_post_fork_child(); #endif #ifdef LINUX_OOM_ADJUST oom_adjust_restore(); #endif } /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ int platform_privileged_uidswap(void) { #ifdef HAVE_CYGWIN /* uid 0 is not special on Cygwin so always try */ return 1; #else return (getuid() == 0 || geteuid() == 0); #endif } /* * This gets called before switching UIDs, and is called even when sshd is * not running as root. */ void platform_setusercontext(struct passwd *pw) { #ifdef WITH_SELINUX /* Cache selinux status for later use */ (void)ssh_selinux_enabled(); #endif #ifdef USE_SOLARIS_PROJECTS /* if solaris projects were detected, set the default now */ if (getuid() == 0 || geteuid() == 0) solaris_set_default_project(pw); #endif #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) if (getuid() == 0 || geteuid() == 0) setpgid(0, 0); # endif #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) /* * If we have both LOGIN_CAP and PAM, we want to establish creds * before calling setusercontext (in session.c:do_setusercontext). */ if (getuid() == 0 || geteuid() == 0) { if (options.use_pam) { do_pam_setcred(use_privsep); } } # endif /* USE_PAM */ #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) if (getuid() == 0 || geteuid() == 0) { /* Sets login uid for accounting */ if (getluid() == -1 && setluid(pw->pw_uid) == -1) error("setluid: %s", strerror(errno)); } #endif } /* * This gets called after we've established the user's groups, and is only * called if sshd is running as root. */ void platform_setusercontext_post_groups(struct passwd *pw) { #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) /* * PAM credentials may take the form of supplementary groups. * These will have been wiped by the above initgroups() call. * Reestablish them here. */ if (options.use_pam) { do_pam_setcred(use_privsep); } #endif /* USE_PAM */ #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) irix_setusercontext(pw); #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ #ifdef _AIX aix_usrinfo(pw); #endif /* _AIX */ #ifdef HAVE_SETPCRED /* * If we have a chroot directory, we set all creds except real * uid which we will need for chroot. If we don't have a * chroot directory, we don't override anything. */ { char **creds = NULL, *chroot_creds[] = { "REAL_USER=root", NULL }; if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) creds = chroot_creds; if (setpcred(pw->pw_name, creds) == -1) fatal("Failed to set process credentials"); } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX ssh_selinux_setup_exec_context(pw->pw_name); #endif } char * platform_krb5_get_principal_name(const char *pw_name) { #ifdef USE_AIX_KRB_NAME return aix_krb5_get_principal_name(pw_name); #else return NULL; #endif } /* * return 1 if the specified uid is a uid that may own a system directory * otherwise 0. */ int platform_sys_dir_uid(uid_t uid) { if (uid == 0) return 1; #ifdef PLATFORM_SYS_DIR_UID if (uid == PLATFORM_SYS_DIR_UID) return 1; #endif return 0; } openssh-7.2p2/platform.h010064400017500001750000000027271267006270000134570ustar00djmdjm/* $Id: platform.h,v 1.9 2013/09/22 09:02:40 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include void platform_pre_listen(void); void platform_pre_fork(void); void platform_pre_restart(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); void platform_setusercontext_post_groups(struct passwd *); char *platform_get_krb5_client(const char *); char *platform_krb5_get_principal_name(const char *); int platform_sys_dir_uid(uid_t); /* in platform-pledge.c */ void platform_pledge_agent(void); void platform_pledge_sftp_server(void); void platform_pledge_mux(void); openssh-7.2p2/poly1305.c010064400017500001750000000110551267006270000131140ustar00djmdjm/* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ /* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */ #include "includes.h" #include #ifdef HAVE_STDINT_H # include #endif #include "poly1305.h" #define mul32x32_64(a,b) ((uint64_t)(a) * (b)) #define U8TO32_LE(p) \ (((uint32_t)((p)[0])) | \ ((uint32_t)((p)[1]) << 8) | \ ((uint32_t)((p)[2]) << 16) | \ ((uint32_t)((p)[3]) << 24)) #define U32TO8_LE(p, v) \ do { \ (p)[0] = (uint8_t)((v)); \ (p)[1] = (uint8_t)((v) >> 8); \ (p)[2] = (uint8_t)((v) >> 16); \ (p)[3] = (uint8_t)((v) >> 24); \ } while (0) void poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { uint32_t t0,t1,t2,t3; uint32_t h0,h1,h2,h3,h4; uint32_t r0,r1,r2,r3,r4; uint32_t s1,s2,s3,s4; uint32_t b, nb; size_t j; uint64_t t[5]; uint64_t f0,f1,f2,f3; uint32_t g0,g1,g2,g3,g4; uint64_t c; unsigned char mp[16]; /* clamp key */ t0 = U8TO32_LE(key+0); t1 = U8TO32_LE(key+4); t2 = U8TO32_LE(key+8); t3 = U8TO32_LE(key+12); /* precompute multipliers */ r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6; r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12; r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18; r3 = t2 & 0x3f03fff; t3 >>= 8; r4 = t3 & 0x00fffff; s1 = r1 * 5; s2 = r2 * 5; s3 = r3 * 5; s4 = r4 * 5; /* init state */ h0 = 0; h1 = 0; h2 = 0; h3 = 0; h4 = 0; /* full blocks */ if (inlen < 16) goto poly1305_donna_atmost15bytes; poly1305_donna_16bytes: m += 16; inlen -= 16; t0 = U8TO32_LE(m-16); t1 = U8TO32_LE(m-12); t2 = U8TO32_LE(m-8); t3 = U8TO32_LE(m-4); h0 += t0 & 0x3ffffff; h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; h4 += (t3 >> 8) | (1 << 24); poly1305_donna_mul: t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1); t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2); t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3); t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4); t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0); h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26); t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26); t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26); t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26); t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26); h0 += b * 5; if (inlen >= 16) goto poly1305_donna_16bytes; /* final bytes */ poly1305_donna_atmost15bytes: if (!inlen) goto poly1305_donna_finish; for (j = 0; j < inlen; j++) mp[j] = m[j]; mp[j++] = 1; for (; j < 16; j++) mp[j] = 0; inlen = 0; t0 = U8TO32_LE(mp+0); t1 = U8TO32_LE(mp+4); t2 = U8TO32_LE(mp+8); t3 = U8TO32_LE(mp+12); h0 += t0 & 0x3ffffff; h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; h4 += (t3 >> 8); goto poly1305_donna_mul; poly1305_donna_finish: b = h0 >> 26; h0 = h0 & 0x3ffffff; h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff; h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff; h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff; h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff; h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff; h1 += b; g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; g4 = h4 + b - (1 << 26); b = (g4 >> 31) - 1; nb = ~b; h0 = (h0 & nb) | (g0 & b); h1 = (h1 & nb) | (g1 & b); h2 = (h2 & nb) | (g2 & b); h3 = (h3 & nb) | (g3 & b); h4 = (h4 & nb) | (g4 & b); f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]); f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]); f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]); f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]); U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32); U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32); U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32); U32TO8_LE(&out[12], f3); } openssh-7.2p2/poly1305.h010064400017500001750000000012051267006270000131150ustar00djmdjm/* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */ /* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ #ifndef POLY1305_H #define POLY1305_H #include #define POLY1305_KEYLEN 32 #define POLY1305_TAGLEN 16 void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, const u_char key[POLY1305_KEYLEN]) __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); #endif /* POLY1305_H */ openssh-7.2p2/progressmeter.c010064400017500001750000000167101267006270000145240ustar00djmdjm/* $OpenBSD: progressmeter.c,v 1.41 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 #include #include #include #include #include #include #include #include #include "progressmeter.h" #include "atomicio.h" #include "misc.h" #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 #define PADDING 1 /* padding between the progress indicators */ #define UPDATE_INTERVAL 1 /* update the progress meter every second */ #define STALL_TIME 5 /* we're stalled after this many seconds */ /* determines whether we can output to the terminal */ static int can_output(void); /* formats and inserts the specified size into the given buffer */ static void format_size(char *, int, off_t); static void format_rate(char *, int, off_t); /* window resizing */ static void sig_winch(int); static void setscreensize(void); /* updates the progressmeter to reflect the current state of the transfer */ void refresh_progress_meter(void); /* signal handler for updating the progress meter */ static void update_progress_meter(int); static time_t start; /* start progress */ static time_t last_update; /* last progress update */ static const char *file; /* name of the file being transferred */ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ static volatile off_t *counter; /* progress counter */ static long stalled; /* how long we have been stalled */ static int bytes_per_second; /* current speed in bytes per second */ static int win_size; /* terminal window size */ static volatile sig_atomic_t win_resized; /* for window resizing */ /* units for format_size */ static const char unit[] = " KMGT"; static int can_output(void) { return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); } static void format_rate(char *buf, int size, off_t bytes) { int i; bytes *= 100; for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; if (i == 0) { i++; bytes = (bytes + 512) / 1024; } snprintf(buf, size, "%3lld.%1lld%c%s", (long long) (bytes + 5) / 100, (long long) (bytes + 5) / 10 % 10, unit[i], i ? "B" : " "); } static void format_size(char *buf, int size, off_t bytes) { int i; for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; snprintf(buf, size, "%4lld%c%s", (long long) bytes, unit[i], i ? "B" : " "); } void refresh_progress_meter(void) { char buf[MAX_WINSIZE + 1]; time_t now; off_t transferred; double elapsed; int percent; off_t bytes_left; int cur_speed; int hours, minutes, seconds; int i, len; int file_len; transferred = *counter - (cur_pos ? cur_pos : start_pos); cur_pos = *counter; now = monotime(); bytes_left = end_pos - cur_pos; if (bytes_left > 0) elapsed = now - last_update; else { elapsed = now - start; /* Calculate true total speed when done */ transferred = end_pos - start_pos; bytes_per_second = 0; } /* calculate speed */ if (elapsed != 0) cur_speed = (transferred / elapsed); else cur_speed = transferred; #define AGE_FACTOR 0.9 if (bytes_per_second != 0) { bytes_per_second = (bytes_per_second * AGE_FACTOR) + (cur_speed * (1.0 - AGE_FACTOR)); } else bytes_per_second = cur_speed; /* filename */ buf[0] = '\0'; file_len = win_size - 35; if (file_len > 0) { len = snprintf(buf, file_len + 1, "\r%s", file); if (len < 0) len = 0; if (len >= file_len + 1) len = file_len; for (i = len; i < file_len; i++) buf[i] = ' '; buf[file_len] = '\0'; } /* percent of transfer done */ if (end_pos != 0) percent = ((float)cur_pos / end_pos) * 100; else percent = 100; snprintf(buf + strlen(buf), win_size - strlen(buf), " %3d%% ", percent); /* amount transferred */ format_size(buf + strlen(buf), win_size - strlen(buf), cur_pos); strlcat(buf, " ", win_size); /* bandwidth usage */ format_rate(buf + strlen(buf), win_size - strlen(buf), (off_t)bytes_per_second); strlcat(buf, "/s ", win_size); /* ETA */ if (!transferred) stalled += elapsed; else stalled = 0; if (stalled >= STALL_TIME) strlcat(buf, "- stalled -", win_size); else if (bytes_per_second == 0 && bytes_left) strlcat(buf, " --:-- ETA", win_size); else { if (bytes_left > 0) seconds = bytes_left / bytes_per_second; else seconds = elapsed; hours = seconds / 3600; seconds -= hours * 3600; minutes = seconds / 60; seconds -= minutes * 60; if (hours != 0) snprintf(buf + strlen(buf), win_size - strlen(buf), "%d:%02d:%02d", hours, minutes, seconds); else snprintf(buf + strlen(buf), win_size - strlen(buf), " %02d:%02d", minutes, seconds); if (bytes_left > 0) strlcat(buf, " ETA", win_size); else strlcat(buf, " ", win_size); } atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); last_update = now; } /*ARGSUSED*/ static void update_progress_meter(int ignore) { int save_errno; save_errno = errno; if (win_resized) { setscreensize(); win_resized = 0; } if (can_output()) refresh_progress_meter(); signal(SIGALRM, update_progress_meter); alarm(UPDATE_INTERVAL); errno = save_errno; } void start_progress_meter(const char *f, off_t filesize, off_t *ctr) { start = last_update = monotime(); file = f; start_pos = *ctr; end_pos = filesize; cur_pos = 0; counter = ctr; stalled = 0; bytes_per_second = 0; setscreensize(); if (can_output()) refresh_progress_meter(); signal(SIGALRM, update_progress_meter); signal(SIGWINCH, sig_winch); alarm(UPDATE_INTERVAL); } void stop_progress_meter(void) { alarm(0); if (!can_output()) return; /* Ensure we complete the progress */ if (cur_pos != end_pos) refresh_progress_meter(); atomicio(vwrite, STDOUT_FILENO, "\n", 1); } /*ARGSUSED*/ static void sig_winch(int sig) { win_resized = 1; } static void setscreensize(void) { struct winsize winsize; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && winsize.ws_col != 0) { if (winsize.ws_col > MAX_WINSIZE) win_size = MAX_WINSIZE; else win_size = winsize.ws_col; } else win_size = DEFAULT_WINSIZE; win_size += 1; /* trailing \0 */ } openssh-7.2p2/progressmeter.h010064400017500001750000000027011267006270000145240ustar00djmdjm/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2002 Nils Nordman. 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. */ void start_progress_meter(const char *, off_t, off_t *); void stop_progress_meter(void); openssh-7.2p2/readconf.c010064400017500001750000002145561267006270000134140ustar00djmdjm/* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for reading the configuration files. * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include #ifdef HAVE_UTIL_H #include #endif #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif #include "xmalloc.h" #include "ssh.h" #include "compat.h" #include "cipher.h" #include "pathnames.h" #include "log.h" #include "sshkey.h" #include "misc.h" #include "readconf.h" #include "match.h" #include "kex.h" #include "mac.h" #include "uidswap.h" #include "myproposal.h" #include "digest.h" /* Format of the configuration file: # Configuration data is parsed as follows: # 1. command line options # 2. user-specific file # 3. system-wide file # Any configuration value is only changed the first time it is set. # Thus, host-specific definitions should be at the beginning of the # configuration file, and defaults at the end. # Host-specific declarations. These may override anything above. A single # host may match multiple declarations; these are processed in the order # that they are given in. Host *.ngs.fi ngs.fi User foo Host fake.com HostName another.host.name.real.org User blaah Port 34289 ForwardX11 no ForwardAgent no Host books.com RemoteForward 9999 shadows.cs.hut.fi:9999 Cipher 3des Host fascist.blob.com Port 23123 User tylonen PasswordAuthentication no Host puukko.hut.fi User t35124p ProxyCommand ssh-proxy %h %p Host *.fr PublicKeyAuthentication no Host *.su Cipher none PasswordAuthentication no Host vpn.fake.com Tunnel yes TunnelDevice 3 # Defaults for various options Host * ForwardAgent no ForwardX11 no PasswordAuthentication yes RSAAuthentication yes RhostsRSAAuthentication yes StrictHostKeyChecking yes TcpKeepAlive no IdentityFile ~/.ssh/identity Port 22 EscapeChar ~ */ /* Keyword tokens. */ typedef enum { oBadOption, oHost, oMatch, oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, oGatewayPorts, oExitOnForwardFailure, oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, oCertificateFile, oAddKeysToAgent, oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, oPubkeyAcceptedKeyTypes, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ static struct { const char *name; OpCodes opcode; } keywords[] = { { "forwardagent", oForwardAgent }, { "forwardx11", oForwardX11 }, { "forwardx11trusted", oForwardX11Trusted }, { "forwardx11timeout", oForwardX11Timeout }, { "exitonforwardfailure", oExitOnForwardFailure }, { "xauthlocation", oXAuthLocation }, { "gatewayports", oGatewayPorts }, { "useprivilegedport", oUsePrivilegedPort }, { "rhostsauthentication", oDeprecated }, { "passwordauthentication", oPasswordAuthentication }, { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, { "kbdinteractivedevices", oKbdInteractiveDevices }, { "rsaauthentication", oRSAAuthentication }, { "pubkeyauthentication", oPubkeyAuthentication }, { "dsaauthentication", oPubkeyAuthentication }, /* alias */ { "rhostsrsaauthentication", oRhostsRSAAuthentication }, { "hostbasedauthentication", oHostbasedAuthentication }, { "challengeresponseauthentication", oChallengeResponseAuthentication }, { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ { "kerberosauthentication", oUnsupported }, { "kerberostgtpassing", oUnsupported }, { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, { "gssapidelegatecredentials", oGssDelegateCreds }, #else { "gssapiauthentication", oUnsupported }, { "gssapidelegatecredentials", oUnsupported }, #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, { "certificatefile", oCertificateFile }, { "addkeystoagent", oAddKeysToAgent }, { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, { "proxycommand", oProxyCommand }, { "port", oPort }, { "cipher", oCipher }, { "ciphers", oCiphers }, { "macs", oMacs }, { "protocol", oProtocol }, { "remoteforward", oRemoteForward }, { "localforward", oLocalForward }, { "user", oUser }, { "host", oHost }, { "match", oMatch }, { "escapechar", oEscapeChar }, { "globalknownhostsfile", oGlobalKnownHostsFile }, { "globalknownhostsfile2", oDeprecated }, { "userknownhostsfile", oUserKnownHostsFile }, { "userknownhostsfile2", oDeprecated }, { "connectionattempts", oConnectionAttempts }, { "batchmode", oBatchMode }, { "checkhostip", oCheckHostIP }, { "stricthostkeychecking", oStrictHostKeyChecking }, { "compression", oCompression }, { "compressionlevel", oCompressionLevel }, { "tcpkeepalive", oTCPKeepAlive }, { "keepalive", oTCPKeepAlive }, /* obsolete */ { "numberofpasswordprompts", oNumberOfPasswordPrompts }, { "loglevel", oLogLevel }, { "dynamicforward", oDynamicForward }, { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, { "bindaddress", oBindAddress }, #ifdef ENABLE_PKCS11 { "smartcarddevice", oPKCS11Provider }, { "pkcs11provider", oPKCS11Provider }, #else { "smartcarddevice", oUnsupported }, { "pkcs11provider", oUnsupported }, #endif { "clearallforwardings", oClearAllForwardings }, { "enablesshkeysign", oEnableSSHKeysign }, { "verifyhostkeydns", oVerifyHostKeyDNS }, { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, { "rekeylimit", oRekeyLimit }, { "connecttimeout", oConnectTimeout }, { "addressfamily", oAddressFamily }, { "serveraliveinterval", oServerAliveInterval }, { "serveralivecountmax", oServerAliveCountMax }, { "sendenv", oSendEnv }, { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "controlpersist", oControlPersist }, { "hashknownhosts", oHashKnownHosts }, { "tunnel", oTunnel }, { "tunneldevice", oTunnelDevice }, { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "useroaming", oDeprecated }, { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, { "proxyusefdpass", oProxyUseFdpass }, { "canonicaldomains", oCanonicalDomains }, { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, { "canonicalizehostname", oCanonicalizeHostname }, { "canonicalizemaxdots", oCanonicalizeMaxDots }, { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, { "streamlocalbindmask", oStreamLocalBindMask }, { "streamlocalbindunlink", oStreamLocalBindUnlink }, { "revokedhostkeys", oRevokedHostKeys }, { "fingerprinthash", oFingerprintHash }, { "updatehostkeys", oUpdateHostkeys }, { "hostbasedkeytypes", oHostbasedKeyTypes }, { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, { "ignoreunknown", oIgnoreUnknown }, { NULL, oBadOption } }; /* * Adds a local TCP/IP port forward to options. Never returns if there is an * error. */ void add_local_forward(Options *options, const struct Forward *newfwd) { struct Forward *fwd; #ifndef NO_IPPORT_RESERVED_CONCEPT extern uid_t original_real_uid; if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && newfwd->listen_path == NULL) fatal("Privileged ports can only be forwarded by root."); #endif options->local_forwards = xreallocarray(options->local_forwards, options->num_local_forwards + 1, sizeof(*options->local_forwards)); fwd = &options->local_forwards[options->num_local_forwards++]; fwd->listen_host = newfwd->listen_host; fwd->listen_port = newfwd->listen_port; fwd->listen_path = newfwd->listen_path; fwd->connect_host = newfwd->connect_host; fwd->connect_port = newfwd->connect_port; fwd->connect_path = newfwd->connect_path; } /* * Adds a remote TCP/IP port forward to options. Never returns if there is * an error. */ void add_remote_forward(Options *options, const struct Forward *newfwd) { struct Forward *fwd; options->remote_forwards = xreallocarray(options->remote_forwards, options->num_remote_forwards + 1, sizeof(*options->remote_forwards)); fwd = &options->remote_forwards[options->num_remote_forwards++]; fwd->listen_host = newfwd->listen_host; fwd->listen_port = newfwd->listen_port; fwd->listen_path = newfwd->listen_path; fwd->connect_host = newfwd->connect_host; fwd->connect_port = newfwd->connect_port; fwd->connect_path = newfwd->connect_path; fwd->handle = newfwd->handle; fwd->allocated_port = 0; } static void clear_forwardings(Options *options) { int i; for (i = 0; i < options->num_local_forwards; i++) { free(options->local_forwards[i].listen_host); free(options->local_forwards[i].listen_path); free(options->local_forwards[i].connect_host); free(options->local_forwards[i].connect_path); } if (options->num_local_forwards > 0) { free(options->local_forwards); options->local_forwards = NULL; } options->num_local_forwards = 0; for (i = 0; i < options->num_remote_forwards; i++) { free(options->remote_forwards[i].listen_host); free(options->remote_forwards[i].listen_path); free(options->remote_forwards[i].connect_host); free(options->remote_forwards[i].connect_path); } if (options->num_remote_forwards > 0) { free(options->remote_forwards); options->remote_forwards = NULL; } options->num_remote_forwards = 0; options->tun_open = SSH_TUNMODE_NO; } void add_certificate_file(Options *options, const char *path, int userprovided) { int i; if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES) fatal("Too many certificate files specified (max %d)", SSH_MAX_CERTIFICATE_FILES); /* Avoid registering duplicates */ for (i = 0; i < options->num_certificate_files; i++) { if (options->certificate_file_userprovided[i] == userprovided && strcmp(options->certificate_files[i], path) == 0) { debug2("%s: ignoring duplicate key %s", __func__, path); return; } } options->certificate_file_userprovided[options->num_certificate_files] = userprovided; options->certificate_files[options->num_certificate_files++] = xstrdup(path); } void add_identity_file(Options *options, const char *dir, const char *filename, int userprovided) { char *path; int i; if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) fatal("Too many identity files specified (max %d)", SSH_MAX_IDENTITY_FILES); if (dir == NULL) /* no dir, filename is absolute */ path = xstrdup(filename); else (void)xasprintf(&path, "%.100s%.100s", dir, filename); /* Avoid registering duplicates */ for (i = 0; i < options->num_identity_files; i++) { if (options->identity_file_userprovided[i] == userprovided && strcmp(options->identity_files[i], path) == 0) { debug2("%s: ignoring duplicate key %s", __func__, path); free(path); return; } } options->identity_file_userprovided[options->num_identity_files] = userprovided; options->identity_files[options->num_identity_files++] = path; } int default_ssh_port(void) { static int port; struct servent *sp; if (port == 0) { sp = getservbyname(SSH_SERVICE_NAME, "tcp"); port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; } return port; } /* * Execute a command in a shell. * Return its exit status or -1 on abnormal exit. */ static int execute_in_shell(const char *cmd) { char *shell; pid_t pid; int devnull, status; extern uid_t original_real_uid; if ((shell = getenv("SHELL")) == NULL) shell = _PATH_BSHELL; /* Need this to redirect subprocess stdin/out */ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) fatal("open(/dev/null): %s", strerror(errno)); debug("Executing command: '%.500s'", cmd); /* Fork and execute the command. */ if ((pid = fork()) == 0) { char *argv[4]; /* Child. Permanently give up superuser privileges. */ permanently_drop_suid(original_real_uid); /* Redirect child stdin and stdout. Leave stderr */ if (dup2(devnull, STDIN_FILENO) == -1) fatal("dup2: %s", strerror(errno)); if (dup2(devnull, STDOUT_FILENO) == -1) fatal("dup2: %s", strerror(errno)); if (devnull > STDERR_FILENO) close(devnull); closefrom(STDERR_FILENO + 1); argv[0] = shell; argv[1] = "-c"; argv[2] = xstrdup(cmd); argv[3] = NULL; execv(argv[0], argv); error("Unable to execute '%.100s': %s", cmd, strerror(errno)); /* Die with signal to make this error apparent to parent. */ signal(SIGTERM, SIG_DFL); kill(getpid(), SIGTERM); _exit(1); } /* Parent. */ if (pid < 0) fatal("%s: fork: %.100s", __func__, strerror(errno)); close(devnull); while (waitpid(pid, &status, 0) == -1) { if (errno != EINTR && errno != EAGAIN) fatal("%s: waitpid: %s", __func__, strerror(errno)); } if (!WIFEXITED(status)) { error("command '%.100s' exited abnormally", cmd); return -1; } debug3("command returned status %d", WEXITSTATUS(status)); return WEXITSTATUS(status); } /* * Parse and execute a Match directive. */ static int match_cfg_line(Options *options, char **condition, struct passwd *pw, const char *host_arg, const char *original_host, int post_canon, const char *filename, int linenum) { char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; const char *ruser; int r, port, this_result, result = 1, attributes = 0, negate; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; /* * Configuration is likely to be incomplete at this point so we * must be prepared to use default values. */ port = options->port <= 0 ? default_ssh_port() : options->port; ruser = options->user == NULL ? pw->pw_name : options->user; if (post_canon) { host = xstrdup(options->hostname); } else if (options->hostname != NULL) { /* NB. Please keep in sync with ssh.c:main() */ host = percent_expand(options->hostname, "h", host_arg, (char *)NULL); } else { host = xstrdup(host_arg); } debug2("checking match for '%s' host %s originally %s", cp, host, original_host); while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { criteria = NULL; this_result = 1; if ((negate = attrib[0] == '!')) attrib++; /* criteria "all" and "canonical" have no argument */ if (strcasecmp(attrib, "all") == 0) { if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { error("%.200s line %d: '%s' cannot be combined " "with other Match attributes", filename, linenum, oattrib); result = -1; goto out; } if (result) result = negate ? 0 : 1; goto out; } attributes++; if (strcasecmp(attrib, "canonical") == 0) { r = !!post_canon; /* force bitmask member to boolean */ if (r == (negate ? 1 : 0)) this_result = result = 0; debug3("%.200s line %d: %smatched '%s'", filename, linenum, this_result ? "" : "not ", oattrib); continue; } /* All other criteria require an argument */ if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { error("Missing Match criteria for %s", attrib); result = -1; goto out; } if (strcasecmp(attrib, "host") == 0) { criteria = xstrdup(host); r = match_hostname(host, arg) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; } else if (strcasecmp(attrib, "originalhost") == 0) { criteria = xstrdup(original_host); r = match_hostname(original_host, arg) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; } else if (strcasecmp(attrib, "user") == 0) { criteria = xstrdup(ruser); r = match_pattern_list(ruser, arg, 0) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; } else if (strcasecmp(attrib, "localuser") == 0) { criteria = xstrdup(pw->pw_name); r = match_pattern_list(pw->pw_name, arg, 0) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; } else if (strcasecmp(attrib, "exec") == 0) { if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); strlcpy(shorthost, thishost, sizeof(shorthost)); shorthost[strcspn(thishost, ".")] = '\0'; snprintf(portstr, sizeof(portstr), "%d", port); cmd = percent_expand(arg, "L", shorthost, "d", pw->pw_dir, "h", host, "l", thishost, "n", original_host, "p", portstr, "r", ruser, "u", pw->pw_name, (char *)NULL); if (result != 1) { /* skip execution if prior predicate failed */ debug3("%.200s line %d: skipped exec " "\"%.100s\"", filename, linenum, cmd); free(cmd); continue; } r = execute_in_shell(cmd); if (r == -1) { fatal("%.200s line %d: match exec " "'%.100s' error", filename, linenum, cmd); } criteria = xstrdup(cmd); free(cmd); /* Force exit status to boolean */ r = r == 0; if (r == (negate ? 1 : 0)) this_result = result = 0; } else { error("Unsupported Match attribute %s", attrib); result = -1; goto out; } debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", filename, linenum, this_result ? "": "not ", oattrib, criteria); free(criteria); } if (attributes == 0) { error("One or more attributes required for Match"); result = -1; goto out; } out: if (result != -1) debug2("match %sfound", result ? "" : "not "); *condition = cp; free(host); return result; } /* Check and prepare a domain name: removes trailing '.' and lowercases */ static void valid_domain(char *name, const char *filename, int linenum) { size_t i, l = strlen(name); u_char c, last = '\0'; if (l == 0) fatal("%s line %d: empty hostname suffix", filename, linenum); if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) fatal("%s line %d: hostname suffix \"%.100s\" " "starts with invalid character", filename, linenum, name); for (i = 0; i < l; i++) { c = tolower((u_char)name[i]); name[i] = (char)c; if (last == '.' && c == '.') fatal("%s line %d: hostname suffix \"%.100s\" contains " "consecutive separators", filename, linenum, name); if (c != '.' && c != '-' && !isalnum(c) && c != '_') /* technically invalid, but common */ fatal("%s line %d: hostname suffix \"%.100s\" contains " "invalid characters", filename, linenum, name); last = c; } if (name[l - 1] == '.') name[l - 1] = '\0'; } /* * Returns the number of the token pointed to by cp or oBadOption. */ static OpCodes parse_token(const char *cp, const char *filename, int linenum, const char *ignored_unknown) { int i; for (i = 0; keywords[i].name; i++) if (strcmp(cp, keywords[i].name) == 0) return keywords[i].opcode; if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown, 1) == 1) return oIgnoredUnknownOption; error("%s: line %d: Bad configuration option: %s", filename, linenum, cp); return oBadOption; } /* Multistate option parsing */ struct multistate { char *key; int value; }; static const struct multistate multistate_flag[] = { { "true", 1 }, { "false", 0 }, { "yes", 1 }, { "no", 0 }, { NULL, -1 } }; static const struct multistate multistate_yesnoask[] = { { "true", 1 }, { "false", 0 }, { "yes", 1 }, { "no", 0 }, { "ask", 2 }, { NULL, -1 } }; static const struct multistate multistate_yesnoaskconfirm[] = { { "true", 1 }, { "false", 0 }, { "yes", 1 }, { "no", 0 }, { "ask", 2 }, { "confirm", 3 }, { NULL, -1 } }; static const struct multistate multistate_addressfamily[] = { { "inet", AF_INET }, { "inet6", AF_INET6 }, { "any", AF_UNSPEC }, { NULL, -1 } }; static const struct multistate multistate_controlmaster[] = { { "true", SSHCTL_MASTER_YES }, { "yes", SSHCTL_MASTER_YES }, { "false", SSHCTL_MASTER_NO }, { "no", SSHCTL_MASTER_NO }, { "auto", SSHCTL_MASTER_AUTO }, { "ask", SSHCTL_MASTER_ASK }, { "autoask", SSHCTL_MASTER_AUTO_ASK }, { NULL, -1 } }; static const struct multistate multistate_tunnel[] = { { "ethernet", SSH_TUNMODE_ETHERNET }, { "point-to-point", SSH_TUNMODE_POINTOPOINT }, { "true", SSH_TUNMODE_DEFAULT }, { "yes", SSH_TUNMODE_DEFAULT }, { "false", SSH_TUNMODE_NO }, { "no", SSH_TUNMODE_NO }, { NULL, -1 } }; static const struct multistate multistate_requesttty[] = { { "true", REQUEST_TTY_YES }, { "yes", REQUEST_TTY_YES }, { "false", REQUEST_TTY_NO }, { "no", REQUEST_TTY_NO }, { "force", REQUEST_TTY_FORCE }, { "auto", REQUEST_TTY_AUTO }, { NULL, -1 } }; static const struct multistate multistate_canonicalizehostname[] = { { "true", SSH_CANONICALISE_YES }, { "false", SSH_CANONICALISE_NO }, { "yes", SSH_CANONICALISE_YES }, { "no", SSH_CANONICALISE_NO }, { "always", SSH_CANONICALISE_ALWAYS }, { NULL, -1 } }; /* * Processes a single option line as used in the configuration files. This * only sets those values that have not already been set. */ #define WHITESPACE " \t\r\n" int process_config_line(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, const char *filename, int linenum, int *activep, int flags) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; char **cpptr, fwdarg[256]; u_int i, *uintptr, max_entries = 0; int negated, opcode, *intptr, value, value2, cmdline = 0; LogLevel *log_level_ptr; long long val64; size_t len; struct Forward fwd; const struct multistate *multistate_ptr; struct allowed_cname *cname; if (activep == NULL) { /* We are processing a command line directive */ cmdline = 1; activep = &cmdline; } /* Strip trailing whitespace */ if ((len = strlen(line)) == 0) return 0; for (len--; len > 0; len--) { if (strchr(WHITESPACE, line[len]) == NULL) break; line[len] = '\0'; } s = line; /* Get the keyword. (Each line is supposed to begin with a keyword). */ if ((keyword = strdelim(&s)) == NULL) return 0; /* Ignore leading whitespace. */ if (*keyword == '\0') keyword = strdelim(&s); if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') return 0; /* Match lowercase keyword */ lowercase(keyword); opcode = parse_token(keyword, filename, linenum, options->ignored_unknown); switch (opcode) { case oBadOption: /* don't panic, but count bad options */ return -1; /* NOTREACHED */ case oIgnoredUnknownOption: debug("%s line %d: Ignored unknown option \"%s\"", filename, linenum, keyword); return 0; case oConnectTimeout: intptr = &options->connection_timeout; parse_time: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%s line %d: missing time value.", filename, linenum); if (strcmp(arg, "none") == 0) value = -1; else if ((value = convtime(arg)) == -1) fatal("%s line %d: invalid time value.", filename, linenum); if (*activep && *intptr == -1) *intptr = value; break; case oForwardAgent: intptr = &options->forward_agent; parse_flag: multistate_ptr = multistate_flag; parse_multistate: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%s line %d: missing argument.", filename, linenum); value = -1; for (i = 0; multistate_ptr[i].key != NULL; i++) { if (strcasecmp(arg, multistate_ptr[i].key) == 0) { value = multistate_ptr[i].value; break; } } if (value == -1) fatal("%s line %d: unsupported option \"%s\".", filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; case oForwardX11: intptr = &options->forward_x11; goto parse_flag; case oForwardX11Trusted: intptr = &options->forward_x11_trusted; goto parse_flag; case oForwardX11Timeout: intptr = &options->forward_x11_timeout; goto parse_time; case oGatewayPorts: intptr = &options->fwd_opts.gateway_ports; goto parse_flag; case oExitOnForwardFailure: intptr = &options->exit_on_forward_failure; goto parse_flag; case oUsePrivilegedPort: intptr = &options->use_privileged_port; goto parse_flag; case oPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; case oKbdInteractiveAuthentication: intptr = &options->kbd_interactive_authentication; goto parse_flag; case oKbdInteractiveDevices: charptr = &options->kbd_interactive_devices; goto parse_string; case oPubkeyAuthentication: intptr = &options->pubkey_authentication; goto parse_flag; case oRSAAuthentication: intptr = &options->rsa_authentication; goto parse_flag; case oRhostsRSAAuthentication: intptr = &options->rhosts_rsa_authentication; goto parse_flag; case oHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; case oChallengeResponseAuthentication: intptr = &options->challenge_response_authentication; goto parse_flag; case oGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; case oGssDelegateCreds: intptr = &options->gss_deleg_creds; goto parse_flag; case oBatchMode: intptr = &options->batch_mode; goto parse_flag; case oCheckHostIP: intptr = &options->check_host_ip; goto parse_flag; case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; goto parse_multistate; case oStrictHostKeyChecking: intptr = &options->strict_host_key_checking; multistate_ptr = multistate_yesnoask; goto parse_multistate; case oCompression: intptr = &options->compression; goto parse_flag; case oTCPKeepAlive: intptr = &options->tcp_keep_alive; goto parse_flag; case oNoHostAuthenticationForLocalhost: intptr = &options->no_host_authentication_for_localhost; goto parse_flag; case oNumberOfPasswordPrompts: intptr = &options->number_of_password_prompts; goto parse_int; case oCompressionLevel: intptr = &options->compression_level; goto parse_int; case oRekeyLimit: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (strcmp(arg, "default") == 0) { val64 = 0; } else { if (scan_scaled(arg, &val64) == -1) fatal("%.200s line %d: Bad number '%s': %s", filename, linenum, arg, strerror(errno)); if (val64 != 0 && val64 < 16) fatal("%.200s line %d: RekeyLimit too small", filename, linenum); } if (*activep && options->rekey_limit == -1) options->rekey_limit = val64; if (s != NULL) { /* optional rekey interval present */ if (strcmp(s, "none") == 0) { (void)strdelim(&s); /* discard */ break; } intptr = &options->rekey_interval; goto parse_time; } break; case oIdentityFile: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (*activep) { intptr = &options->num_identity_files; if (*intptr >= SSH_MAX_IDENTITY_FILES) fatal("%.200s line %d: Too many identity files specified (max %d).", filename, linenum, SSH_MAX_IDENTITY_FILES); add_identity_file(options, NULL, arg, flags & SSHCONF_USERCONF); } break; case oCertificateFile: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (*activep) { intptr = &options->num_certificate_files; if (*intptr >= SSH_MAX_CERTIFICATE_FILES) { fatal("%.200s line %d: Too many certificate " "files specified (max %d).", filename, linenum, SSH_MAX_CERTIFICATE_FILES); } add_certificate_file(options, arg, flags & SSHCONF_USERCONF); } break; case oXAuthLocation: charptr=&options->xauth_location; goto parse_string; case oUser: charptr = &options->user; parse_string: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case oGlobalKnownHostsFile: cpptr = (char **)&options->system_hostfiles; uintptr = &options->num_system_hostfiles; max_entries = SSH_MAX_HOSTS_FILES; parse_char_array: if (*activep && *uintptr == 0) { while ((arg = strdelim(&s)) != NULL && *arg != '\0') { if ((*uintptr) >= max_entries) fatal("%s line %d: " "too many authorized keys files.", filename, linenum); cpptr[(*uintptr)++] = xstrdup(arg); } } return 0; case oUserKnownHostsFile: cpptr = (char **)&options->user_hostfiles; uintptr = &options->num_user_hostfiles; max_entries = SSH_MAX_HOSTS_FILES; goto parse_char_array; case oHostName: charptr = &options->hostname; goto parse_string; case oHostKeyAlias: charptr = &options->host_key_alias; goto parse_string; case oPreferredAuthentications: charptr = &options->preferred_authentications; goto parse_string; case oBindAddress: charptr = &options->bind_address; goto parse_string; case oPKCS11Provider: charptr = &options->pkcs11_provider; goto parse_string; case oProxyCommand: charptr = &options->proxy_command; parse_command: if (s == NULL) fatal("%.200s line %d: Missing argument.", filename, linenum); len = strspn(s, WHITESPACE "="); if (*activep && *charptr == NULL) *charptr = xstrdup(s + len); return 0; case oPort: intptr = &options->port; parse_int: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (arg[0] < '0' || arg[0] > '9') fatal("%.200s line %d: Bad number.", filename, linenum); /* Octal, decimal, or hex format? */ value = strtol(arg, &endofnumber, 0); if (arg == endofnumber) fatal("%.200s line %d: Bad number.", filename, linenum); if (*activep && *intptr == -1) *intptr = value; break; case oConnectionAttempts: intptr = &options->connection_attempts; goto parse_int; case oCipher: intptr = &options->cipher; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); value = cipher_number(arg); if (value == -1) fatal("%.200s line %d: Bad cipher '%s'.", filename, linenum, arg ? arg : ""); if (*activep && *intptr == -1) *intptr = value; break; case oCiphers: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", filename, linenum, arg ? arg : ""); if (*activep && options->ciphers == NULL) options->ciphers = xstrdup(arg); break; case oMacs: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (!mac_valid(*arg == '+' ? arg + 1 : arg)) fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", filename, linenum, arg ? arg : ""); if (*activep && options->macs == NULL) options->macs = xstrdup(arg); break; case oKexAlgorithms: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", filename, linenum, arg ? arg : ""); if (*activep && options->kex_algorithms == NULL) options->kex_algorithms = xstrdup(arg); break; case oHostKeyAlgorithms: charptr = &options->hostkeyalgorithms; parse_keytypes: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) fatal("%s line %d: Bad key types '%s'.", filename, linenum, arg ? arg : ""); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case oProtocol: intptr = &options->protocol; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); value = proto_spec(arg); if (value == SSH_PROTO_UNKNOWN) fatal("%.200s line %d: Bad protocol spec '%s'.", filename, linenum, arg ? arg : ""); if (*activep && *intptr == SSH_PROTO_UNKNOWN) *intptr = value; break; case oLogLevel: log_level_ptr = &options->log_level; arg = strdelim(&s); value = log_level_number(arg); if (value == SYSLOG_LEVEL_NOT_SET) fatal("%.200s line %d: unsupported log level '%s'", filename, linenum, arg ? arg : ""); if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) *log_level_ptr = (LogLevel) value; break; case oLocalForward: case oRemoteForward: case oDynamicForward: arg = strdelim(&s); if (arg == NULL || *arg == '\0') fatal("%.200s line %d: Missing port argument.", filename, linenum); if (opcode == oLocalForward || opcode == oRemoteForward) { arg2 = strdelim(&s); if (arg2 == NULL || *arg2 == '\0') fatal("%.200s line %d: Missing target argument.", filename, linenum); /* construct a string for parse_forward */ snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); } else if (opcode == oDynamicForward) { strlcpy(fwdarg, arg, sizeof(fwdarg)); } if (parse_forward(&fwd, fwdarg, opcode == oDynamicForward ? 1 : 0, opcode == oRemoteForward ? 1 : 0) == 0) fatal("%.200s line %d: Bad forwarding specification.", filename, linenum); if (*activep) { if (opcode == oLocalForward || opcode == oDynamicForward) add_local_forward(options, &fwd); else if (opcode == oRemoteForward) add_remote_forward(options, &fwd); } break; case oClearAllForwardings: intptr = &options->clear_forwardings; goto parse_flag; case oHost: if (cmdline) fatal("Host directive not supported as a command-line " "option"); *activep = 0; arg2 = NULL; while ((arg = strdelim(&s)) != NULL && *arg != '\0') { negated = *arg == '!'; if (negated) arg++; if (match_pattern(host, arg)) { if (negated) { debug("%.200s line %d: Skipping Host " "block because of negated match " "for %.100s", filename, linenum, arg); *activep = 0; break; } if (!*activep) arg2 = arg; /* logged below */ *activep = 1; } } if (*activep) debug("%.200s line %d: Applying options for %.100s", filename, linenum, arg2); /* Avoid garbage check below, as strdelim is done. */ return 0; case oMatch: if (cmdline) fatal("Host directive not supported as a command-line " "option"); value = match_cfg_line(options, &s, pw, host, original_host, flags & SSHCONF_POSTCANON, filename, linenum); if (value < 0) fatal("%.200s line %d: Bad Match condition", filename, linenum); *activep = value; break; case oEscapeChar: intptr = &options->escape_char; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (strcmp(arg, "none") == 0) value = SSH_ESCAPECHAR_NONE; else if (arg[1] == '\0') value = (u_char) arg[0]; else if (arg[0] == '^' && arg[2] == 0 && (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) value = (u_char) arg[1] & 31; else { fatal("%.200s line %d: Bad escape character.", filename, linenum); /* NOTREACHED */ value = 0; /* Avoid compiler warning. */ } if (*activep && *intptr == -1) *intptr = value; break; case oAddressFamily: intptr = &options->address_family; multistate_ptr = multistate_addressfamily; goto parse_multistate; case oEnableSSHKeysign: intptr = &options->enable_ssh_keysign; goto parse_flag; case oIdentitiesOnly: intptr = &options->identities_only; goto parse_flag; case oServerAliveInterval: intptr = &options->server_alive_interval; goto parse_time; case oServerAliveCountMax: intptr = &options->server_alive_count_max; goto parse_int; case oSendEnv: while ((arg = strdelim(&s)) != NULL && *arg != '\0') { if (strchr(arg, '=') != NULL) fatal("%s line %d: Invalid environment name.", filename, linenum); if (!*activep) continue; if (options->num_send_env >= MAX_SEND_ENV) fatal("%s line %d: too many send env.", filename, linenum); options->send_env[options->num_send_env++] = xstrdup(arg); } break; case oControlPath: charptr = &options->control_path; goto parse_string; case oControlMaster: intptr = &options->control_master; multistate_ptr = multistate_controlmaster; goto parse_multistate; case oControlPersist: /* no/false/yes/true, or a time spec */ intptr = &options->control_persist; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing ControlPersist" " argument.", filename, linenum); value = 0; value2 = 0; /* timeout */ if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) value = 0; else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) value = 1; else if ((value2 = convtime(arg)) >= 0) value = 1; else fatal("%.200s line %d: Bad ControlPersist argument.", filename, linenum); if (*activep && *intptr == -1) { *intptr = value; options->control_persist_timeout = value2; } break; case oHashKnownHosts: intptr = &options->hash_known_hosts; goto parse_flag; case oTunnel: intptr = &options->tun_open; multistate_ptr = multistate_tunnel; goto parse_multistate; case oTunnelDevice: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); value = a2tun(arg, &value2); if (value == SSH_TUNID_ERR) fatal("%.200s line %d: Bad tun device.", filename, linenum); if (*activep) { options->tun_local = value; options->tun_remote = value2; } break; case oLocalCommand: charptr = &options->local_command; goto parse_command; case oPermitLocalCommand: intptr = &options->permit_local_command; goto parse_flag; case oVisualHostKey: intptr = &options->visual_host_key; goto parse_flag; case oIPQoS: arg = strdelim(&s); if ((value = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad IPQoS value: %s", filename, linenum, arg); arg = strdelim(&s); if (arg == NULL) value2 = value; else if ((value2 = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad IPQoS value: %s", filename, linenum, arg); if (*activep) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; } break; case oRequestTTY: intptr = &options->request_tty; multistate_ptr = multistate_requesttty; goto parse_multistate; case oIgnoreUnknown: charptr = &options->ignored_unknown; goto parse_string; case oProxyUseFdpass: intptr = &options->proxy_use_fdpass; goto parse_flag; case oCanonicalDomains: value = options->num_canonical_domains != 0; while ((arg = strdelim(&s)) != NULL && *arg != '\0') { valid_domain(arg, filename, linenum); if (!*activep || value) continue; if (options->num_canonical_domains >= MAX_CANON_DOMAINS) fatal("%s line %d: too many hostname suffixes.", filename, linenum); options->canonical_domains[ options->num_canonical_domains++] = xstrdup(arg); } break; case oCanonicalizePermittedCNAMEs: value = options->num_permitted_cnames != 0; while ((arg = strdelim(&s)) != NULL && *arg != '\0') { /* Either '*' for everything or 'list:list' */ if (strcmp(arg, "*") == 0) arg2 = arg; else { lowercase(arg); if ((arg2 = strchr(arg, ':')) == NULL || arg2[1] == '\0') { fatal("%s line %d: " "Invalid permitted CNAME \"%s\"", filename, linenum, arg); } *arg2 = '\0'; arg2++; } if (!*activep || value) continue; if (options->num_permitted_cnames >= MAX_CANON_DOMAINS) fatal("%s line %d: too many permitted CNAMEs.", filename, linenum); cname = options->permitted_cnames + options->num_permitted_cnames++; cname->source_list = xstrdup(arg); cname->target_list = xstrdup(arg2); } break; case oCanonicalizeHostname: intptr = &options->canonicalize_hostname; multistate_ptr = multistate_canonicalizehostname; goto parse_multistate; case oCanonicalizeMaxDots: intptr = &options->canonicalize_max_dots; goto parse_int; case oCanonicalizeFallbackLocal: intptr = &options->canonicalize_fallback_local; goto parse_flag; case oStreamLocalBindMask: arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); /* Parse mode in octal format */ value = strtol(arg, &endofnumber, 8); if (arg == endofnumber || value < 0 || value > 0777) fatal("%.200s line %d: Bad mask.", filename, linenum); options->fwd_opts.streamlocal_bind_mask = (mode_t)value; break; case oStreamLocalBindUnlink: intptr = &options->fwd_opts.streamlocal_bind_unlink; goto parse_flag; case oRevokedHostKeys: charptr = &options->revoked_host_keys; goto parse_string; case oFingerprintHash: intptr = &options->fingerprint_hash; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if ((value = ssh_digest_alg_by_name(arg)) == -1) fatal("%.200s line %d: Invalid hash algorithm \"%s\".", filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; case oUpdateHostkeys: intptr = &options->update_hostkeys; multistate_ptr = multistate_yesnoask; goto parse_multistate; case oHostbasedKeyTypes: charptr = &options->hostbased_key_types; goto parse_keytypes; case oPubkeyAcceptedKeyTypes: charptr = &options->pubkey_key_types; goto parse_keytypes; case oAddKeysToAgent: intptr = &options->add_keys_to_agent; multistate_ptr = multistate_yesnoaskconfirm; goto parse_multistate; case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); return 0; case oUnsupported: error("%s line %d: Unsupported option \"%s\"", filename, linenum, keyword); return 0; default: fatal("%s: Unimplemented opcode %d", __func__, opcode); } /* Check that there is no garbage at end of line. */ if ((arg = strdelim(&s)) != NULL && *arg != '\0') { fatal("%.200s line %d: garbage at end of line; \"%.200s\".", filename, linenum, arg); } return 0; } /* * Reads the config file and modifies the options accordingly. Options * should already be initialized before this call. This never returns if * there is an error. If the file does not exist, this returns 0. */ int read_config_file(const char *filename, struct passwd *pw, const char *host, const char *original_host, Options *options, int flags) { FILE *f; char line[1024]; int active, linenum; int bad_options = 0; if ((f = fopen(filename, "r")) == NULL) return 0; if (flags & SSHCONF_CHECKPERM) { struct stat sb; if (fstat(fileno(f), &sb) == -1) fatal("fstat %s: %s", filename, strerror(errno)); if (((sb.st_uid != 0 && sb.st_uid != getuid()) || (sb.st_mode & 022) != 0)) fatal("Bad owner or permissions on %s", filename); } debug("Reading configuration data %.200s", filename); /* * Mark that we are now processing the options. This flag is turned * on/off by Host specifications. */ active = 1; linenum = 0; while (fgets(line, sizeof(line), f)) { /* Update line number counter. */ linenum++; if (process_config_line(options, pw, host, original_host, line, filename, linenum, &active, flags) != 0) bad_options++; } fclose(f); if (bad_options > 0) fatal("%s: terminating, %d bad configuration options", filename, bad_options); return 1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ int option_clear_or_none(const char *o) { return o == NULL || strcasecmp(o, "none") == 0; } /* * Initializes options to special values that indicate that they have not yet * been set. Read_config_file will only set options with this value. Options * are processed in the following order: command line, user config file, * system config file. Last, fill_default_options is called. */ void initialize_options(Options * options) { memset(options, 'X', sizeof(*options)); options->forward_agent = -1; options->forward_x11 = -1; options->forward_x11_trusted = -1; options->forward_x11_timeout = -1; options->exit_on_forward_failure = -1; options->xauth_location = NULL; options->fwd_opts.gateway_ports = -1; options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; options->fwd_opts.streamlocal_bind_unlink = -1; options->use_privileged_port = -1; options->rsa_authentication = -1; options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; options->gss_deleg_creds = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; options->rhosts_rsa_authentication = -1; options->hostbased_authentication = -1; options->batch_mode = -1; options->check_host_ip = -1; options->strict_host_key_checking = -1; options->compression = -1; options->tcp_keep_alive = -1; options->compression_level = -1; options->port = -1; options->address_family = -1; options->connection_attempts = -1; options->connection_timeout = -1; options->number_of_password_prompts = -1; options->cipher = -1; options->ciphers = NULL; options->macs = NULL; options->kex_algorithms = NULL; options->hostkeyalgorithms = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->num_identity_files = 0; options->num_certificate_files = 0; options->hostname = NULL; options->host_key_alias = NULL; options->proxy_command = NULL; options->user = NULL; options->escape_char = -1; options->num_system_hostfiles = 0; options->num_user_hostfiles = 0; options->local_forwards = NULL; options->num_local_forwards = 0; options->remote_forwards = NULL; options->num_remote_forwards = 0; options->clear_forwardings = -1; options->log_level = SYSLOG_LEVEL_NOT_SET; options->preferred_authentications = NULL; options->bind_address = NULL; options->pkcs11_provider = NULL; options->enable_ssh_keysign = - 1; options->no_host_authentication_for_localhost = - 1; options->identities_only = - 1; options->rekey_limit = - 1; options->rekey_interval = -1; options->verify_host_key_dns = -1; options->server_alive_interval = -1; options->server_alive_count_max = -1; options->num_send_env = 0; options->control_path = NULL; options->control_master = -1; options->control_persist = -1; options->control_persist_timeout = 0; options->hash_known_hosts = -1; options->tun_open = -1; options->tun_local = -1; options->tun_remote = -1; options->local_command = NULL; options->permit_local_command = -1; options->add_keys_to_agent = -1; options->visual_host_key = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; options->proxy_use_fdpass = -1; options->ignored_unknown = NULL; options->num_canonical_domains = 0; options->num_permitted_cnames = 0; options->canonicalize_max_dots = -1; options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; options->fingerprint_hash = -1; options->update_hostkeys = -1; options->hostbased_key_types = NULL; options->pubkey_key_types = NULL; } /* * A petite version of fill_default_options() that just fills the options * needed for hostname canonicalization to proceed. */ void fill_default_options_for_canonicalization(Options *options) { if (options->canonicalize_max_dots == -1) options->canonicalize_max_dots = 1; if (options->canonicalize_fallback_local == -1) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; } /* * Called after processing other sources of option data, this fills those * options for which no value has been specified with their default values. */ void fill_default_options(Options * options) { if (options->forward_agent == -1) options->forward_agent = 0; if (options->forward_x11 == -1) options->forward_x11 = 0; if (options->forward_x11_trusted == -1) options->forward_x11_trusted = 0; if (options->forward_x11_timeout == -1) options->forward_x11_timeout = 1200; if (options->exit_on_forward_failure == -1) options->exit_on_forward_failure = 0; if (options->xauth_location == NULL) options->xauth_location = _PATH_XAUTH; if (options->fwd_opts.gateway_ports == -1) options->fwd_opts.gateway_ports = 0; if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) options->fwd_opts.streamlocal_bind_unlink = 0; if (options->use_privileged_port == -1) options->use_privileged_port = 0; if (options->rsa_authentication == -1) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_deleg_creds == -1) options->gss_deleg_creds = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) options->kbd_interactive_authentication = 1; if (options->rhosts_rsa_authentication == -1) options->rhosts_rsa_authentication = 0; if (options->hostbased_authentication == -1) options->hostbased_authentication = 0; if (options->batch_mode == -1) options->batch_mode = 0; if (options->check_host_ip == -1) options->check_host_ip = 1; if (options->strict_host_key_checking == -1) options->strict_host_key_checking = 2; /* 2 is default */ if (options->compression == -1) options->compression = 0; if (options->tcp_keep_alive == -1) options->tcp_keep_alive = 1; if (options->compression_level == -1) options->compression_level = 6; if (options->port == -1) options->port = 0; /* Filled in ssh_connect. */ if (options->address_family == -1) options->address_family = AF_UNSPEC; if (options->connection_attempts == -1) options->connection_attempts = 1; if (options->number_of_password_prompts == -1) options->number_of_password_prompts = 3; /* Selected in ssh_login(). */ if (options->cipher == -1) options->cipher = SSH_CIPHER_NOT_SET; /* options->hostkeyalgorithms, default set in myproposals.h */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_2; if (options->add_keys_to_agent == -1) options->add_keys_to_agent = 0; if (options->num_identity_files == 0) { if (options->protocol & SSH_PROTO_1) { add_identity_file(options, "~/", _PATH_SSH_CLIENT_IDENTITY, 0); } if (options->protocol & SSH_PROTO_2) { add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0); add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); #ifdef OPENSSL_HAS_ECC add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0); #endif add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ED25519, 0); } } if (options->escape_char == -1) options->escape_char = '~'; if (options->num_system_hostfiles == 0) { options->system_hostfiles[options->num_system_hostfiles++] = xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); options->system_hostfiles[options->num_system_hostfiles++] = xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); } if (options->num_user_hostfiles == 0) { options->user_hostfiles[options->num_user_hostfiles++] = xstrdup(_PATH_SSH_USER_HOSTFILE); options->user_hostfiles[options->num_user_hostfiles++] = xstrdup(_PATH_SSH_USER_HOSTFILE2); } if (options->log_level == SYSLOG_LEVEL_NOT_SET) options->log_level = SYSLOG_LEVEL_INFO; if (options->clear_forwardings == 1) clear_forwardings(options); if (options->no_host_authentication_for_localhost == - 1) options->no_host_authentication_for_localhost = 0; if (options->identities_only == -1) options->identities_only = 0; if (options->enable_ssh_keysign == -1) options->enable_ssh_keysign = 0; if (options->rekey_limit == -1) options->rekey_limit = 0; if (options->rekey_interval == -1) options->rekey_interval = 0; if (options->verify_host_key_dns == -1) options->verify_host_key_dns = 0; if (options->server_alive_interval == -1) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { options->control_persist = 0; options->control_persist_timeout = 0; } if (options->hash_known_hosts == -1) options->hash_known_hosts = 0; if (options->tun_open == -1) options->tun_open = SSH_TUNMODE_NO; if (options->tun_local == -1) options->tun_local = SSH_TUNID_ANY; if (options->tun_remote == -1) options->tun_remote = SSH_TUNID_ANY; if (options->permit_local_command == -1) options->permit_local_command = 0; if (options->visual_host_key == -1) options->visual_host_key = 0; if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_LOWDELAY; if (options->ip_qos_bulk == -1) options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->request_tty == -1) options->request_tty = REQUEST_TTY_AUTO; if (options->proxy_use_fdpass == -1) options->proxy_use_fdpass = 0; if (options->canonicalize_max_dots == -1) options->canonicalize_max_dots = 1; if (options->canonicalize_fallback_local == -1) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; if (options->update_hostkeys == -1) options->update_hostkeys = 0; if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, &options->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, &options->pubkey_key_types) != 0) fatal("%s: kex_assemble_names failed", __func__); #define CLEAR_ON_NONE(v) \ do { \ if (option_clear_or_none(v)) { \ free(v); \ v = NULL; \ } \ } while(0) CLEAR_ON_NONE(options->local_command); CLEAR_ON_NONE(options->proxy_command); CLEAR_ON_NONE(options->control_path); CLEAR_ON_NONE(options->revoked_host_keys); /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ } struct fwdarg { char *arg; int ispath; }; /* * parse_fwd_field * parses the next field in a port forwarding specification. * sets fwd to the parsed field and advances p past the colon * or sets it to NULL at end of string. * returns 0 on success, else non-zero. */ static int parse_fwd_field(char **p, struct fwdarg *fwd) { char *ep, *cp = *p; int ispath = 0; if (*cp == '\0') { *p = NULL; return -1; /* end of string */ } /* * A field escaped with square brackets is used literally. * XXX - allow ']' to be escaped via backslash? */ if (*cp == '[') { /* find matching ']' */ for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { if (*ep == '/') ispath = 1; } /* no matching ']' or not at end of field. */ if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) return -1; /* NUL terminate the field and advance p past the colon */ *ep++ = '\0'; if (*ep != '\0') *ep++ = '\0'; fwd->arg = cp + 1; fwd->ispath = ispath; *p = ep; return 0; } for (cp = *p; *cp != '\0'; cp++) { switch (*cp) { case '\\': memmove(cp, cp + 1, strlen(cp + 1) + 1); if (*cp == '\0') return -1; break; case '/': ispath = 1; break; case ':': *cp++ = '\0'; goto done; } } done: fwd->arg = *p; fwd->ispath = ispath; *p = cp; return 0; } /* * parse_forward * parses a string containing a port forwarding specification of the form: * dynamicfwd == 0 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath * listenpath:connectpath * dynamicfwd == 1 * [listenhost:]listenport * returns number of arguments parsed or zero on error */ int parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) { struct fwdarg fwdargs[4]; char *p, *cp; int i; memset(fwd, 0, sizeof(*fwd)); memset(fwdargs, 0, sizeof(fwdargs)); cp = p = xstrdup(fwdspec); /* skip leading spaces */ while (isspace((u_char)*cp)) cp++; for (i = 0; i < 4; ++i) { if (parse_fwd_field(&cp, &fwdargs[i]) != 0) break; } /* Check for trailing garbage */ if (cp != NULL && *cp != '\0') { i = 0; /* failure */ } switch (i) { case 1: if (fwdargs[0].ispath) { fwd->listen_path = xstrdup(fwdargs[0].arg); fwd->listen_port = PORT_STREAMLOCAL; } else { fwd->listen_host = NULL; fwd->listen_port = a2port(fwdargs[0].arg); } fwd->connect_host = xstrdup("socks"); break; case 2: if (fwdargs[0].ispath && fwdargs[1].ispath) { fwd->listen_path = xstrdup(fwdargs[0].arg); fwd->listen_port = PORT_STREAMLOCAL; fwd->connect_path = xstrdup(fwdargs[1].arg); fwd->connect_port = PORT_STREAMLOCAL; } else if (fwdargs[1].ispath) { fwd->listen_host = NULL; fwd->listen_port = a2port(fwdargs[0].arg); fwd->connect_path = xstrdup(fwdargs[1].arg); fwd->connect_port = PORT_STREAMLOCAL; } else { fwd->listen_host = xstrdup(fwdargs[0].arg); fwd->listen_port = a2port(fwdargs[1].arg); fwd->connect_host = xstrdup("socks"); } break; case 3: if (fwdargs[0].ispath) { fwd->listen_path = xstrdup(fwdargs[0].arg); fwd->listen_port = PORT_STREAMLOCAL; fwd->connect_host = xstrdup(fwdargs[1].arg); fwd->connect_port = a2port(fwdargs[2].arg); } else if (fwdargs[2].ispath) { fwd->listen_host = xstrdup(fwdargs[0].arg); fwd->listen_port = a2port(fwdargs[1].arg); fwd->connect_path = xstrdup(fwdargs[2].arg); fwd->connect_port = PORT_STREAMLOCAL; } else { fwd->listen_host = NULL; fwd->listen_port = a2port(fwdargs[0].arg); fwd->connect_host = xstrdup(fwdargs[1].arg); fwd->connect_port = a2port(fwdargs[2].arg); } break; case 4: fwd->listen_host = xstrdup(fwdargs[0].arg); fwd->listen_port = a2port(fwdargs[1].arg); fwd->connect_host = xstrdup(fwdargs[2].arg); fwd->connect_port = a2port(fwdargs[3].arg); break; default: i = 0; /* failure */ } free(p); if (dynamicfwd) { if (!(i == 1 || i == 2)) goto fail_free; } else { if (!(i == 3 || i == 4)) { if (fwd->connect_path == NULL && fwd->listen_path == NULL) goto fail_free; } if (fwd->connect_port <= 0 && fwd->connect_path == NULL) goto fail_free; } if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || (!remotefwd && fwd->listen_port == 0)) goto fail_free; if (fwd->connect_host != NULL && strlen(fwd->connect_host) >= NI_MAXHOST) goto fail_free; /* XXX - if connecting to a remote socket, max sun len may not match this host */ if (fwd->connect_path != NULL && strlen(fwd->connect_path) >= PATH_MAX_SUN) goto fail_free; if (fwd->listen_host != NULL && strlen(fwd->listen_host) >= NI_MAXHOST) goto fail_free; if (fwd->listen_path != NULL && strlen(fwd->listen_path) >= PATH_MAX_SUN) goto fail_free; return (i); fail_free: free(fwd->connect_host); fwd->connect_host = NULL; free(fwd->connect_path); fwd->connect_path = NULL; free(fwd->listen_host); fwd->listen_host = NULL; free(fwd->listen_path); fwd->listen_path = NULL; return (0); } /* XXX the following is a near-vebatim copy from servconf.c; refactor */ static const char * fmt_multistate_int(int val, const struct multistate *m) { u_int i; for (i = 0; m[i].key != NULL; i++) { if (m[i].value == val) return m[i].key; } return "UNKNOWN"; } static const char * fmt_intarg(OpCodes code, int val) { if (val == -1) return "unset"; switch (code) { case oAddressFamily: return fmt_multistate_int(val, multistate_addressfamily); case oVerifyHostKeyDNS: case oStrictHostKeyChecking: case oUpdateHostkeys: return fmt_multistate_int(val, multistate_yesnoask); case oControlMaster: return fmt_multistate_int(val, multistate_controlmaster); case oTunnel: return fmt_multistate_int(val, multistate_tunnel); case oRequestTTY: return fmt_multistate_int(val, multistate_requesttty); case oCanonicalizeHostname: return fmt_multistate_int(val, multistate_canonicalizehostname); case oFingerprintHash: return ssh_digest_alg_name(val); case oProtocol: switch (val) { case SSH_PROTO_1: return "1"; case SSH_PROTO_2: return "2"; case (SSH_PROTO_1|SSH_PROTO_2): return "2,1"; default: return "UNKNOWN"; } default: switch (val) { case 0: return "no"; case 1: return "yes"; default: return "UNKNOWN"; } } } static const char * lookup_opcode_name(OpCodes code) { u_int i; for (i = 0; keywords[i].name != NULL; i++) if (keywords[i].opcode == code) return(keywords[i].name); return "UNKNOWN"; } static void dump_cfg_int(OpCodes code, int val) { printf("%s %d\n", lookup_opcode_name(code), val); } static void dump_cfg_fmtint(OpCodes code, int val) { printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); } static void dump_cfg_string(OpCodes code, const char *val) { if (val == NULL) return; printf("%s %s\n", lookup_opcode_name(code), val); } static void dump_cfg_strarray(OpCodes code, u_int count, char **vals) { u_int i; for (i = 0; i < count; i++) printf("%s %s\n", lookup_opcode_name(code), vals[i]); } static void dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) { u_int i; printf("%s", lookup_opcode_name(code)); for (i = 0; i < count; i++) printf(" %s", vals[i]); printf("\n"); } static void dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) { const struct Forward *fwd; u_int i; /* oDynamicForward */ for (i = 0; i < count; i++) { fwd = &fwds[i]; if (code == oDynamicForward && strcmp(fwd->connect_host, "socks") != 0) continue; if (code == oLocalForward && strcmp(fwd->connect_host, "socks") == 0) continue; printf("%s", lookup_opcode_name(code)); if (fwd->listen_port == PORT_STREAMLOCAL) printf(" %s", fwd->listen_path); else if (fwd->listen_host == NULL) printf(" %d", fwd->listen_port); else { printf(" [%s]:%d", fwd->listen_host, fwd->listen_port); } if (code != oDynamicForward) { if (fwd->connect_port == PORT_STREAMLOCAL) printf(" %s", fwd->connect_path); else if (fwd->connect_host == NULL) printf(" %d", fwd->connect_port); else { printf(" [%s]:%d", fwd->connect_host, fwd->connect_port); } } printf("\n"); } } void dump_client_config(Options *o, const char *host) { int i; char vbuf[5]; /* This is normally prepared in ssh_kex2 */ if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) fatal("%s: kex_assemble_names failed", __func__); /* Most interesting options first: user, host, port */ dump_cfg_string(oUser, o->user); dump_cfg_string(oHostName, host); dump_cfg_int(oPort, o->port); /* Flag options */ dump_cfg_fmtint(oAddressFamily, o->address_family); dump_cfg_fmtint(oBatchMode, o->batch_mode); dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); dump_cfg_fmtint(oCompression, o->compression); dump_cfg_fmtint(oControlMaster, o->control_master); dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); dump_cfg_fmtint(oProtocol, o->protocol); dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); dump_cfg_fmtint(oRequestTTY, o->request_tty); dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); dump_cfg_fmtint(oTunnel, o->tun_open); dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); /* Integer options */ dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); dump_cfg_int(oCompressionLevel, o->compression_level); dump_cfg_int(oConnectionAttempts, o->connection_attempts); dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); dump_cfg_int(oServerAliveInterval, o->server_alive_interval); /* String options */ dump_cfg_string(oBindAddress, o->bind_address); dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); dump_cfg_string(oControlPath, o->control_path); dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms); dump_cfg_string(oHostKeyAlias, o->host_key_alias); dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); dump_cfg_string(oLocalCommand, o->local_command); dump_cfg_string(oLogLevel, log_level_name(o->log_level)); dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); dump_cfg_string(oProxyCommand, o->proxy_command); dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); dump_cfg_string(oXAuthLocation, o->xauth_location); /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); /* String array options */ dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); /* Special cases */ /* oConnectTimeout */ if (o->connection_timeout == -1) printf("connecttimeout none\n"); else dump_cfg_int(oConnectTimeout, o->connection_timeout); /* oTunnelDevice */ printf("tunneldevice"); if (o->tun_local == SSH_TUNID_ANY) printf(" any"); else printf(" %d", o->tun_local); if (o->tun_remote == SSH_TUNID_ANY) printf(":any"); else printf(":%d", o->tun_remote); printf("\n"); /* oCanonicalizePermittedCNAMEs */ if ( o->num_permitted_cnames > 0) { printf("canonicalizePermittedcnames"); for (i = 0; i < o->num_permitted_cnames; i++) { printf(" %s:%s", o->permitted_cnames[i].source_list, o->permitted_cnames[i].target_list); } printf("\n"); } /* oCipher */ if (o->cipher != SSH_CIPHER_NOT_SET) printf("Cipher %s\n", cipher_name(o->cipher)); /* oControlPersist */ if (o->control_persist == 0 || o->control_persist_timeout == 0) dump_cfg_fmtint(oControlPersist, o->control_persist); else dump_cfg_int(oControlPersist, o->control_persist_timeout); /* oEscapeChar */ if (o->escape_char == SSH_ESCAPECHAR_NONE) printf("escapechar none\n"); else { vis(vbuf, o->escape_char, VIS_WHITE, 0); printf("escapechar %s\n", vbuf); } /* oIPQoS */ printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); printf("%s\n", iptos2str(o->ip_qos_bulk)); /* oRekeyLimit */ printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, o->rekey_interval); /* oStreamLocalBindMask */ printf("streamlocalbindmask 0%o\n", o->fwd_opts.streamlocal_bind_mask); } openssh-7.2p2/readconf.h010064400017500001750000000166161267006270000134160ustar00djmdjm/* $OpenBSD: readconf.h,v 1.113 2016/01/14 16:17:40 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for reading the configuration file. * * 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 READCONF_H #define READCONF_H /* Data structure for representing option data. */ #define MAX_SEND_ENV 256 #define SSH_MAX_HOSTS_FILES 32 #define MAX_CANON_DOMAINS 32 #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { char *source_list; char *target_list; }; typedef struct { int forward_agent; /* Forward authentication agent. */ int forward_x11; /* Forward X11 display. */ int forward_x11_timeout; /* Expiration for Cookies */ int forward_x11_trusted; /* Trust Forward X11 display. */ int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */ char *xauth_location; /* Location for xauth program */ struct ForwardOptions fwd_opts; /* forwarding options */ int use_privileged_port; /* Don't use privileged port if false. */ int rhosts_rsa_authentication; /* Try rhosts with RSA * authentication. */ int rsa_authentication; /* Try RSA authentication. */ int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ int gss_deleg_creds; /* Delegate GSS credentials */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ int batch_mode; /* Batch mode: do not ask for passwords. */ int check_host_ip; /* Also keep track of keys for IP address */ int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ int compression_level; /* Compression level 1 (fast) to 9 * (best). */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ int address_family; int connection_attempts; /* Max attempts (seconds) before * giving up */ int connection_timeout; /* Max time (seconds) before * aborting connection attempt */ int number_of_password_prompts; /* Max number of password * prompts. */ int cipher; /* Cipher to use. */ char *ciphers; /* SSH2 ciphers in order of preference. */ char *macs; /* SSH2 macs in order of preference. */ char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ char *kex_algorithms; /* SSH2 kex methods in order of preference. */ int protocol; /* Protocol in order of preference. */ char *hostname; /* Real host to connect. */ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ char *system_hostfiles[SSH_MAX_HOSTS_FILES]; u_int num_user_hostfiles; /* Path for $HOME/.ssh/known_hosts */ char *user_hostfiles[SSH_MAX_HOSTS_FILES]; char *preferred_authentications; char *bind_address; /* local socket address for connection to sshd */ char *pkcs11_provider; /* PKCS#11 provider */ int verify_host_key_dns; /* Verify host key using DNS */ int num_identity_files; /* Number of files for RSA/DSA identities. */ char *identity_files[SSH_MAX_IDENTITY_FILES]; int identity_file_userprovided[SSH_MAX_IDENTITY_FILES]; struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; int num_certificate_files; /* Number of extra certificates for ssh. */ char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int add_keys_to_agent; /* Local TCP/IP forward requests. */ int num_local_forwards; struct Forward *local_forwards; /* Remote TCP/IP forward requests. */ int num_remote_forwards; struct Forward *remote_forwards; int clear_forwardings; int enable_ssh_keysign; int64_t rekey_limit; int rekey_interval; int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; int server_alive_count_max; int num_send_env; char *send_env[MAX_SEND_ENV]; char *control_path; int control_master; int control_persist; /* ControlPersist flag */ int control_persist_timeout; /* ControlPersist timeout (seconds) */ int hash_known_hosts; int tun_open; /* tun(4) */ int tun_local; /* force tun device (optional) */ int tun_remote; /* force tun device (optional) */ char *local_command; int permit_local_command; int visual_host_key; int request_tty; int proxy_use_fdpass; int num_canonical_domains; char *canonical_domains[MAX_CANON_DOMAINS]; int canonicalize_hostname; int canonicalize_max_dots; int canonicalize_fallback_local; int num_permitted_cnames; struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS]; char *revoked_host_keys; int fingerprint_hash; int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ char *hostbased_key_types; char *pubkey_key_types; char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; #define SSH_CANONICALISE_NO 0 #define SSH_CANONICALISE_YES 1 #define SSH_CANONICALISE_ALWAYS 2 #define SSHCTL_MASTER_NO 0 #define SSHCTL_MASTER_YES 1 #define SSHCTL_MASTER_AUTO 2 #define SSHCTL_MASTER_ASK 3 #define SSHCTL_MASTER_AUTO_ASK 4 #define REQUEST_TTY_AUTO 0 #define REQUEST_TTY_NO 1 #define REQUEST_TTY_YES 2 #define REQUEST_TTY_FORCE 3 #define SSHCONF_CHECKPERM 1 /* check permissions on config file */ #define SSHCONF_USERCONF 2 /* user provided config file not system */ #define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ #define SSH_UPDATE_HOSTKEYS_NO 0 #define SSH_UPDATE_HOSTKEYS_YES 1 #define SSH_UPDATE_HOSTKEYS_ASK 2 void initialize_options(Options *); void fill_default_options(Options *); void fill_default_options_for_canonicalization(Options *); int process_config_line(Options *, struct passwd *, const char *, const char *, char *, const char *, int, int *, int); int read_config_file(const char *, struct passwd *, const char *, const char *, Options *, int); int parse_forward(struct Forward *, const char *, int, int); int default_ssh_port(void); int option_clear_or_none(const char *); void dump_client_config(Options *o, const char *host); void add_local_forward(Options *, const struct Forward *); void add_remote_forward(Options *, const struct Forward *); void add_identity_file(Options *, const char *, const char *, int); void add_certificate_file(Options *, const char *, int); #endif /* READCONF_H */ openssh-7.2p2/readpass.c010064400017500001750000000120251267006270000134200ustar00djmdjm/* $OpenBSD: readpass.c,v 1.51 2015/12/11 00:20:04 mmcc 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 #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include #include "xmalloc.h" #include "misc.h" #include "pathnames.h" #include "log.h" #include "ssh.h" #include "uidswap.h" static char * ssh_askpass(char *askpass, const char *msg) { pid_t pid, ret; size_t len; char *pass; int p[2], status; char buf[1024]; void (*osigchld)(int); if (fflush(stdout) != 0) error("ssh_askpass: fflush: %s", strerror(errno)); if (askpass == NULL) fatal("internal error: askpass undefined"); if (pipe(p) < 0) { error("ssh_askpass: pipe: %s", strerror(errno)); return NULL; } osigchld = signal(SIGCHLD, SIG_DFL); if ((pid = fork()) < 0) { error("ssh_askpass: fork: %s", strerror(errno)); signal(SIGCHLD, osigchld); return NULL; } if (pid == 0) { permanently_drop_suid(getuid()); close(p[0]); if (dup2(p[1], STDOUT_FILENO) < 0) fatal("ssh_askpass: dup2: %s", strerror(errno)); execlp(askpass, askpass, msg, (char *)NULL); fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); } close(p[1]); len = 0; do { ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len); if (r == -1 && errno == EINTR) continue; if (r <= 0) break; len += r; } while (sizeof(buf) - 1 - len > 0); buf[len] = '\0'; close(p[0]); while ((ret = waitpid(pid, &status, 0)) < 0) if (errno != EINTR) break; signal(SIGCHLD, osigchld); if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { explicit_bzero(buf, sizeof(buf)); return NULL; } buf[strcspn(buf, "\r\n")] = '\0'; pass = xstrdup(buf); explicit_bzero(buf, sizeof(buf)); return pass; } /* * Reads a passphrase from /dev/tty with echo turned off/on. Returns the * passphrase (allocated with xmalloc). Exits if EOF is encountered. If * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no * tty is available */ char * read_passphrase(const char *prompt, int flags) { char *askpass = NULL, *ret, buf[1024]; int rppflags, use_askpass = 0, ttyfd; rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF; if (flags & RP_USE_ASKPASS) use_askpass = 1; else if (flags & RP_ALLOW_STDIN) { if (!isatty(STDIN_FILENO)) { debug("read_passphrase: stdin is not a tty"); use_askpass = 1; } } else { rppflags |= RPP_REQUIRE_TTY; ttyfd = open(_PATH_TTY, O_RDWR); if (ttyfd >= 0) close(ttyfd); else { debug("read_passphrase: can't open %s: %s", _PATH_TTY, strerror(errno)); use_askpass = 1; } } if ((flags & RP_USE_ASKPASS) && getenv("DISPLAY") == NULL) return (flags & RP_ALLOW_EOF) ? NULL : xstrdup(""); if (use_askpass && getenv("DISPLAY")) { if (getenv(SSH_ASKPASS_ENV)) askpass = getenv(SSH_ASKPASS_ENV); else askpass = _PATH_SSH_ASKPASS_DEFAULT; if ((ret = ssh_askpass(askpass, prompt)) == NULL) if (!(flags & RP_ALLOW_EOF)) return xstrdup(""); return ret; } if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) { if (flags & RP_ALLOW_EOF) return NULL; return xstrdup(""); } ret = xstrdup(buf); explicit_bzero(buf, sizeof(buf)); return ret; } int ask_permission(const char *fmt, ...) { va_list args; char *p, prompt[1024]; int allowed = 0; va_start(args, fmt); vsnprintf(prompt, sizeof(prompt), fmt, args); va_end(args); p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF); if (p != NULL) { /* * Accept empty responses and responses consisting * of the word "yes" as affirmative. */ if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0) allowed = 1; free(p); } return (allowed); } openssh-7.2p2/regress004075500017500001750000000000001267006270000130505ustar00djmdjmopenssh-7.2p2/regress/.cvsignore010064400017500001750000000004511267006270000151240ustar00djmdjm*-agent *.copy *.log *.prv *.pub actual authorized_keys_* batch copy.dd* data expect host.rsa* key.* known_hosts krl-* modpipe remote_pid revoked-* revoked-ca revoked-keyid revoked-serials rsa rsa1 sftp-server.sh ssh-log-wrapper.sh ssh_config ssh_proxy* sshd_config sshd_proxy* t*.out t*.out[0-9] openssh-7.2p2/regress/Makefile010064400017500001750000000143571267006270000145760ustar00djmdjm# $OpenBSD: Makefile,v 1.82 2015/09/24 06:16:53 djm Exp $ REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec tests: prep $(REGRESS_TARGETS) # Interop tests are not run by default interop interop-tests: t-exec-interop prep: test "x${USE_VALGRIND}" = "x" || mkdir -p $(OBJ)/valgrind-out clean: for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} rm -rf $(OBJ).putty distclean: clean LTESTS= connect \ proxy-connect \ connect-privsep \ proto-version \ proto-mismatch \ exit-status \ envpass \ transfer \ banner \ rekey \ stderr-data \ stderr-after-eof \ broken-pipe \ try-ciphers \ yes-head \ login-timeout \ agent \ agent-getpeereid \ agent-timeout \ agent-ptrace \ keyscan \ keygen-change \ keygen-convert \ key-options \ scp \ sftp \ sftp-chroot \ sftp-cmds \ sftp-badcmds \ sftp-batch \ sftp-glob \ sftp-perm \ reconfigure \ dynamic-forward \ forwarding \ multiplex \ reexec \ brokenkeys \ cfgparse \ cfgmatch \ addrmatch \ localcommand \ forcecommand \ portnum \ keytype \ kextype \ cert-hostkey \ cert-userkey \ host-expand \ keys-command \ forward-control \ integrity \ krl \ multipubkey \ limit-keytype \ hostkey-agent \ keygen-knownhosts \ hostkey-rotate \ principals-command \ cert-file # dhgex \ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp #LTESTS= cipher-speed USER!= id -un CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ t12.out t12.out.pub \ authorized_keys_${USER} known_hosts pidfile testdata \ ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ ls.copy banner.in banner.out empty.in \ scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ known_hosts-cert host_ca_key* cert_host_key* cert_user_key* \ putty.rsa2 sshd_proxy_orig ssh_proxy_bak \ key.rsa-* key.dsa-* key.ecdsa-* \ authorized_principals_${USER} expect actual ready \ sshd_proxy.* authorized_keys_${USER}.* modpipe revoked-* krl-* \ ssh.log failed-ssh.log sshd.log failed-sshd.log \ regress.log failed-regress.log ssh-log-wrapper.sh \ sftp-server.sh sftp-server.log sftp.log setuid-allowed \ data ed25519-agent ed25519-agent.pub key.ed25519-512 \ key.ed25519-512.pub netcat host_krl_* host_revoked_* \ kh.* user_*key* agent-key.* known_hosts.* hkr.* SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} # Enable all malloc(3) randomisations and checks TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" TEST_SSH_SSHKEYGEN?=ssh-keygen CPPFLAGS=-I.. t1: ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv t2: cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out chmod 600 $(OBJ)/t2.out ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub t3: ${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub t4: ${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t4.ok t5: ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t5.ok t6: ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 chmod 600 $(OBJ)/t6.out1 ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 $(OBJ)/t7.out: ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@ t7: $(OBJ)/t7.out ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null $(OBJ)/t8.out: ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@ t8: $(OBJ)/t8.out ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null $(OBJ)/t9.out: test "${TEST_SSH_ECC}" != yes || \ ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@ t9: $(OBJ)/t9.out test "${TEST_SSH_ECC}" != yes || \ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null test "${TEST_SSH_ECC}" != yes || \ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null $(OBJ)/t10.out: ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -f $@ t10: $(OBJ)/t10.out ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null t11: ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t11.ok $(OBJ)/t12.out: ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $@ t12: $(OBJ)/t12.out ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ echo "run test $${TEST}" ... 1>&2; \ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ done t-exec-interop: ${INTEROP_TESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ echo "run test $${TEST}" ... 1>&2; \ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ done # Not run by default interop: ${INTEROP_TARGETS} # Unit tests, built by top-level Makefile unit: set -e ; if test -z "${SKIP_UNIT}" ; then \ V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \ $$V ${.OBJDIR}/unittests/kex/test_kex ; \ $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ -d ${.CURDIR}/unittests/hostkeys/testdata ; \ fi openssh-7.2p2/regress/README.regress010064400017500001750000000072631267006270000154650ustar00djmdjmOverview. $ ./configure && make tests You'll see some progress info. A failure will cause either the make to abort or the driver script to report a "FATAL" failure. The test consists of 2 parts. The first is the file-based tests which is driven by the Makefile, and the second is a set of network or proxycommand based tests, which are driven by a driver script (test-exec.sh) which is called multiple times by the Makefile. Failures in the first part will cause the Makefile to return an error. Failures in the second part will print a "FATAL" message for the failed test and continue. OpenBSD has a system-wide regression test suite. OpenSSH Portable's test suite is based on OpenBSD's with modifications. Environment variables. SUDO: path to sudo command, if desired. Note that some systems (notably systems using PAM) require sudo to execute some tests. TEST_SSH_TRACE: set to "yes" for verbose output from tests TEST_SSH_QUIET: set to "yes" to suppress non-fatal output. TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER OBJ: used by test scripts to access build dir. TEST_SHELL: shell used for running the test scripts. TEST_SSH_PORT: TCP port to be used for the listening tests. TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config before running each test. TEST_SSH_SSHD_CONFOPTS: Configuration directives to be added to sshd_config before running each test. Individual tests. You can run an individual test from the top-level Makefile, eg: $ make tests LTESTS=agent-timeout If you need to manipulate the environment more you can invoke test-exec.sh directly if you set up the path to find the binaries under test and the test scripts themselves, for example: $ cd regress $ PATH=`pwd`/..:$PATH:. TEST_SHELL=/bin/sh sh test-exec.sh `pwd` \ agent-timeout.sh ok agent timeout test Files. test-exec.sh: the main test driver. Sets environment, creates config files and keys and runs the specified test. At the time of writing, the individual tests are: agent-timeout.sh: agent timeout test agent.sh: simple agent test broken-pipe.sh: broken pipe test connect-privsep.sh: proxy connect with privsep connect.sh: simple connect exit-status.sh: remote exit status forwarding.sh: local and remote forwarding keygen-change.sh: change passphrase for key keyscan.sh: keyscan proto-mismatch.sh: protocol version mismatch proto-version.sh: sshd version with different protocol combinations proxy-connect.sh: proxy connect sftp.sh: basic sftp put/get ssh-com-client.sh: connect with ssh.com client ssh-com-keygen.sh: ssh.com key import ssh-com-sftp.sh: basic sftp put/get with ssh.com server ssh-com.sh: connect to ssh.com server stderr-after-eof.sh: stderr data after eof stderr-data.sh: stderr data transfer transfer.sh: transfer data try-ciphers.sh: try ciphers yes-head.sh: yes pipe head Problems? Run the failing test with shell tracing (-x) turned on: $ PATH=`pwd`/..:$PATH:. sh -x test-exec.sh `pwd` agent-timeout.sh Failed tests can be difficult to diagnose. Suggestions: - run the individual test via ./test-exec.sh `pwd` [testname] - set LogLevel to VERBOSE in test-exec.sh and enable syslogging of auth.debug (eg to /var/log/authlog). Known Issues. - Similarly, if you do not have "scp" in your system's $PATH then the multiplex scp tests will fail (since the system's shell startup scripts will determine where the shell started by sshd will look for scp). - Recent GNU coreutils deprecate "head -[n]": this will cause the yes-head test to fail. The old behaviour can be restored by setting (and exporting) _POSIX2_VERSION=199209 before running the tests. $Id: README.regress,v 1.12 2011/05/05 03:48:42 djm Exp $ openssh-7.2p2/regress/addrmatch.sh010064400017500001750000000041001267006270000154020ustar00djmdjm# $OpenBSD: addrmatch.sh,v 1.4 2012/05/13 01:42:32 dtucker Exp $ # Placed in the Public Domain. tid="address match" mv $OBJ/sshd_proxy $OBJ/sshd_proxy_bak run_trial() { user="$1"; addr="$2"; host="$3"; laddr="$4"; lport="$5" expected="$6"; descr="$7" verbose "test $descr for $user $addr $host" result=`${SSHD} -f $OBJ/sshd_proxy -T \ -C user=${user},addr=${addr},host=${host},laddr=${laddr},lport=${lport} | \ awk '/^forcecommand/ {print $2}'` if [ "$result" != "$expected" ]; then fail "failed '$descr' expected $expected got $result" fi } cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy cat >>$OBJ/sshd_proxy < /dev/null r=$? if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else chmod 644 ${SSH_AUTH_SOCK} ssh-add -l > /dev/null 2>&1 r=$? if [ $r -ne 1 ]; then fail "ssh-add failed with $r != 1" fi < /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l 2>/dev/null r=$? if [ $r -lt 2 ]; then fail "ssh-add did not fail for ${UNPRIV}: $r < 2" fi trace "kill agent" ${SSHAGENT} -k > /dev/null fi rm -f ${OBJ}/agent openssh-7.2p2/regress/agent-pkcs11.sh010064400017500001750000000035641267006270000156660ustar00djmdjm# $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent test" TEST_SSH_PIN="" TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" # setup environment for soft-pkcs11 token SOFTPKCS11RC=$OBJ/pkcs11.info export SOFTPKCS11RC # prevent ssh-agent from calling ssh-askpass SSH_ASKPASS=/usr/bin/true export SSH_ASKPASS unset DISPLAY # start command w/o tty, so ssh-add accepts pin from stdin notty() { perl -e 'use POSIX; POSIX::setsid(); if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@" } trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else trace "generating key/cert" rm -f $OBJ/pkcs11.key $OBJ/pkcs11.crt openssl genrsa -out $OBJ/pkcs11.key 2048 > /dev/null 2>&1 chmod 600 $OBJ/pkcs11.key openssl req -key $OBJ/pkcs11.key -new -x509 \ -out $OBJ/pkcs11.crt -text -subj '/CN=pkcs11 test' > /dev/null printf "a\ta\t$OBJ/pkcs11.crt\t$OBJ/pkcs11.key" > $SOFTPKCS11RC # add to authorized keys ${SSHKEYGEN} -y -f $OBJ/pkcs11.key > $OBJ/authorized_keys_$USER trace "add pkcs11 key to agent" echo ${TEST_SSH_PIN} | notty ${SSHADD} -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -s failed: exit code $r" fi trace "pkcs11 list via agent" ${SSHADD} -l > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -l failed: exit code $r" fi trace "pkcs11 connect via agent" ${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5 r=$? if [ $r -ne 5 ]; then fail "ssh connect failed (exit code $r)" fi trace "remove pkcs11 keys" echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -e failed: exit code $r" fi trace "kill agent" ${SSHAGENT} -k > /dev/null fi openssh-7.2p2/regress/agent-ptrace.sh010064400017500001750000000024721267006270000160370ustar00djmdjm# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $ # Placed in the Public Domain. tid="disallow agent ptrace attach" if have_prog uname ; then case `uname` in AIX|CYGWIN*|OSF1) echo "skipped (not supported on this platform)" exit 0 ;; esac fi if [ "x$USER" = "xroot" ]; then echo "Skipped: running as root" exit 0 fi if have_prog gdb ; then : ok else echo "skipped (gdb not found)" exit 0 fi if $OBJ/setuid-allowed ${SSHAGENT} ; then : ok else echo "skipped (${SSHAGENT} is mounted on a no-setuid filesystem)" exit 0 fi if test -z "$SUDO" ; then echo "skipped (SUDO not set)" exit 0 else $SUDO chown 0 ${SSHAGENT} $SUDO chgrp 0 ${SSHAGENT} $SUDO chmod 2755 ${SSHAGENT} fi trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else # ls -l ${SSH_AUTH_SOCK} gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF quit EOF r=$? if [ $r -ne 0 ]; then fail "gdb failed: exit code $r" fi egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out r=$? rm -f ${OBJ}/gdb.out if [ $r -ne 0 ]; then fail "ptrace succeeded?: exit code $r" fi trace "kill agent" ${SSHAGENT} -k > /dev/null fi openssh-7.2p2/regress/agent-timeout.sh010064400017500001750000000016401267006270000162430ustar00djmdjm# $OpenBSD: agent-timeout.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="agent timeout test" SSHAGENT_TIMEOUT=10 trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else trace "add keys with timeout" for t in ${SSH_KEYTYPES}; do ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh-add did succeed exit code 0" fi done n=`${SSHADD} -l 2> /dev/null | wc -l` trace "agent has $n keys" if [ $n -ne 2 ]; then fail "ssh-add -l did not return 2 keys: $n" fi trace "sleeping 2*${SSHAGENT_TIMEOUT} seconds" sleep ${SSHAGENT_TIMEOUT} sleep ${SSHAGENT_TIMEOUT} ${SSHADD} -l 2> /dev/null | grep 'The agent has no identities.' >/dev/null if [ $? -ne 0 ]; then fail "ssh-add -l still returns keys after timeout" fi trace "kill agent" ${SSHAGENT} -k > /dev/null fi openssh-7.2p2/regress/agent.sh010064400017500001750000000040041267006270000145540ustar00djmdjm# $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple agent test" SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 if [ $? -ne 2 ]; then fail "ssh-add -l did not fail with exit code 2" fi trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else ${SSHADD} -l > /dev/null 2>&1 if [ $? -ne 1 ]; then fail "ssh-add -l did not fail with exit code 1" fi trace "overwrite authorized keys" printf '' > $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do # generate user key for agent rm -f $OBJ/$t-agent ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ fail "ssh-keygen for $t-agent failed" # add to authorized keys cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER # add privat key to agent ${SSHADD} $OBJ/$t-agent > /dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh-add did succeed exit code 0" fi done ${SSHADD} -l > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -l failed: exit code $r" fi # the same for full pubkey output ${SSHADD} -L > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -L failed: exit code $r" fi trace "simple connect via agent" for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p r=$? if [ $r -ne 5$p ]; then fail "ssh connect with protocol $p failed (exit code $r)" fi done trace "agent forwarding" for p in ${SSH_PROTOCOLS}; do ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -l via agent fwd proto $p failed (exit code $r)" fi ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \ "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p" r=$? if [ $r -ne 5$p ]; then fail "agent fwd proto $p failed (exit code $r)" fi done trace "delete all agent keys" ${SSHADD} -D > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-add -D failed: exit code $r" fi trace "kill agent" ${SSHAGENT} -k > /dev/null fi openssh-7.2p2/regress/banner.sh010064400017500001750000000024001267006270000147210ustar00djmdjm# $OpenBSD: banner.sh,v 1.2 2003/10/11 11:49:49 dtucker Exp $ # Placed in the Public Domain. tid="banner" echo "Banner $OBJ/banner.in" >> $OBJ/sshd_proxy rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in touch $OBJ/empty.in trace "test missing banner file" verbose "test $tid: missing banner file" ( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ cmp $OBJ/empty.in $OBJ/banner.out ) || \ fail "missing banner file" for s in 0 10 100 1000 10000 100000 ; do if [ "$s" = "0" ]; then # create empty banner touch $OBJ/banner.in elif [ "$s" = "10" ]; then # create 10-byte banner file echo "abcdefghi" >$OBJ/banner.in else # increase size 10x cp $OBJ/banner.in $OBJ/banner.out for i in 0 1 2 3 4 5 6 7 8 ; do cat $OBJ/banner.out >> $OBJ/banner.in done fi trace "test banner size $s" verbose "test $tid: size $s" ( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ cmp $OBJ/banner.in $OBJ/banner.out ) || \ fail "banner size $s mismatch" done trace "test suppress banner (-q)" verbose "test $tid: suppress banner (-q)" ( ${SSH} -q -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ cmp $OBJ/empty.in $OBJ/banner.out ) || \ fail "suppress banner (-q)" rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in openssh-7.2p2/regress/broken-pipe.sh010064400017500001750000000005571267006270000157020ustar00djmdjm# $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="broken pipe test" for p in ${SSH_PROTOCOLS}; do trace "protocol $p" for i in 1 2 3 4; do ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true r=$? if [ $r -ne 0 ]; then fail "broken pipe returns $r for protocol $p" fi done done openssh-7.2p2/regress/brokenkeys.sh010064400017500001750000000007351267006270000156410ustar00djmdjm# $OpenBSD: brokenkeys.sh,v 1.1 2004/10/29 23:59:22 djm Exp $ # Placed in the Public Domain. tid="broken keys" KEYS="$OBJ/authorized_keys_${USER}" start_sshd mv ${KEYS} ${KEYS}.bak # Truncated key echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS cat ${KEYS}.bak >> ${KEYS} cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER ${SSH} -2 -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed" fi mv ${KEYS}.bak ${KEYS} openssh-7.2p2/regress/cert-file.sh010064400017500001750000000102201267006270000153250ustar00djmdjm# $OpenBSD: cert-file.sh,v 1.2 2015/09/24 07:15:39 djm Exp $ # Placed in the Public Domain. tid="ssh with certificates" rm -f $OBJ/user_ca_key* $OBJ/user_key* rm -f $OBJ/cert_user_key* # Create a CA key ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key1 ||\ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key2 ||\ fatal "ssh-keygen failed" # Make some keys and certificates. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \ fatal "ssh-keygen failed" # Move the certificate to a different address to better control # when it is offered. ${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \ -z $$ -n ${USER} $OBJ/user_key1 || fail "couldn't sign user_key1 with user_ca_key1" mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_1.pub ${SSHKEYGEN} -q -s $OBJ/user_ca_key2 -I "regress user key for $USER" \ -z $$ -n ${USER} $OBJ/user_key1 || fail "couldn't sign user_key1 with user_ca_key2" mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub trace 'try with identity files' opts="-F $OBJ/ssh_proxy -oIdentitiesOnly=yes" opts2="$opts -i $OBJ/user_key1 -i $OBJ/user_key2" echo "cert-authority $(cat $OBJ/user_ca_key1.pub)" > $OBJ/authorized_keys_$USER for p in ${SSH_PROTOCOLS}; do # Just keys should fail ${SSH} $opts2 somehost exit 5$p r=$? if [ $r -eq 5$p ]; then fail "ssh succeeded with no certs in protocol $p" fi # Keys with untrusted cert should fail. opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" ${SSH} $opts3 somehost exit 5$p r=$? if [ $r -eq 5$p ]; then fail "ssh succeeded with bad cert in protocol $p" fi # Good cert with bad key should fail. opts3="$opts -i $OBJ/user_key2" opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" ${SSH} $opts3 somehost exit 5$p r=$? if [ $r -eq 5$p ]; then fail "ssh succeeded with no matching key in protocol $p" fi # Keys with one trusted cert, should succeed. opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" ${SSH} $opts3 somehost exit 5$p r=$? if [ $r -ne 5$p ]; then fail "ssh failed with trusted cert and key in protocol $p" fi # Multiple certs and keys, with one trusted cert, should succeed. opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" ${SSH} $opts3 somehost exit 5$p r=$? if [ $r -ne 5$p ]; then fail "ssh failed with multiple certs in protocol $p" fi #Keys with trusted certificate specified in config options, should succeed. opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" ${SSH} $opts3 somehost exit 5$p r=$? if [ $r -ne 5$p ]; then fail "ssh failed with trusted cert in config in protocol $p" fi done #next, using an agent in combination with the keys SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 if [ $? -ne 2 ]; then fatal "ssh-add -l did not fail with exit code 2" fi trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? if [ $r -ne 0 ]; then fatal "could not start ssh-agent: exit code $r" fi # add private keys to agent ${SSHADD} -k $OBJ/user_key2 > /dev/null 2>&1 if [ $? -ne 0 ]; then fatal "ssh-add did not succeed with exit code 0" fi ${SSHADD} -k $OBJ/user_key1 > /dev/null 2>&1 if [ $? -ne 0 ]; then fatal "ssh-add did not succeed with exit code 0" fi # try ssh with the agent and certificates # note: ssh agent only uses certificates in protocol 2 opts="-F $OBJ/ssh_proxy" # with no certificates, shoud fail ${SSH} -2 $opts somehost exit 52 if [ $? -eq 52 ]; then fail "ssh connect with agent in protocol 2 succeeded with no cert" fi #with an untrusted certificate, should fail opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub" ${SSH} -2 $opts somehost exit 52 if [ $? -eq 52 ]; then fail "ssh connect with agent in protocol 2 succeeded with bad cert" fi #with an additional trusted certificate, should succeed opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub" ${SSH} -2 $opts somehost exit 52 if [ $? -ne 52 ]; then fail "ssh connect with agent in protocol 2 failed with good cert" fi trace "kill agent" ${SSHAGENT} -k > /dev/null #cleanup rm -f $OBJ/user_ca_key* $OBJ/user_key* rm -f $OBJ/cert_user_key* openssh-7.2p2/regress/cert-hostkey.sh010064400017500001750000000226171267006270000161110ustar00djmdjm# $OpenBSD: cert-hostkey.sh,v 1.13 2015/07/10 06:23:25 markus Exp $ # Placed in the Public Domain. tid="certified host keys" rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/host_revoked_* rm -f $OBJ/cert_host_key* $OBJ/host_krl_* # Allow all hostkey/pubkey types, prefer certs for the client types="" for i in `$SSH -Q key`; do if [ -z "$types" ]; then types="$i" continue fi case "$i" in *cert*) types="$i,$types";; *) types="$types,$i";; esac done ( echo "HostKeyAlgorithms ${types}" echo "PubkeyAcceptedKeyTypes *" ) >> $OBJ/ssh_proxy cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak ( echo "HostKeyAlgorithms *" echo "PubkeyAcceptedKeyTypes *" ) >> $OBJ/sshd_proxy_bak HOSTS='localhost-with-alias,127.0.0.1,::1' # Create a CA key and add it to known hosts. Ed25519 chosed for speed. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\ fail "ssh-keygen of host_ca_key failed" ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert # Plain text revocation files touch $OBJ/host_revoked_empty touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` # Prepare certificate, plain key and CA KRLs ${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" ${SSHKEYGEN} -kf $OBJ/host_krl_plain || fatal "KRL init failed" ${SSHKEYGEN} -kf $OBJ/host_krl_cert || fatal "KRL init failed" ${SSHKEYGEN} -kf $OBJ/host_krl_ca $OBJ/host_ca_key.pub \ || fatal "KRL init failed" # Generate and sign host keys serial=1 for ktype in $PLAIN_TYPES ; do verbose "$tid: sign host ${ktype} cert" # Generate and sign a host key ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_host_key_${ktype} || \ fatal "ssh-keygen of cert_host_key_${ktype} failed" ${SSHKEYGEN} -ukf $OBJ/host_krl_plain \ $OBJ/cert_host_key_${ktype}.pub || fatal "KRL update failed" cat $OBJ/cert_host_key_${ktype}.pub >> $OBJ/host_revoked_plain ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -z $serial \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || fatal "couldn't sign cert_host_key_${ktype}" ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ $OBJ/cert_host_key_${ktype}-cert.pub || \ fatal "KRL update failed" cat $OBJ/cert_host_key_${ktype}-cert.pub >> $OBJ/host_revoked_cert serial=`expr $serial + 1` done attempt_connect() { _ident="$1" _expect_success="$2" shift; shift verbose "$tid: $_ident expect success $_expect_success" cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ "$@" -F $OBJ/ssh_proxy somehost true _r=$? if [ "x$_expect_success" = "xyes" ] ; then if [ $_r -ne 0 ]; then fail "ssh cert connect $_ident failed" fi else if [ $_r -eq 0 ]; then fail "ssh cert connect $_ident succeeded unexpectedly" fi fi } # Basic connect and revocation tests. for privsep in yes no ; do for ktype in $PLAIN_TYPES ; do verbose "$tid: host ${ktype} cert connect privsep $privsep" ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${ktype} echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub echo UsePrivilegeSeparation $privsep ) > $OBJ/sshd_proxy # test name expect success attempt_connect "$ktype basic connect" "yes" attempt_connect "$ktype empty KRL" "yes" \ -oRevokedHostKeys=$OBJ/host_krl_empty attempt_connect "$ktype KRL w/ plain key revoked" "no" \ -oRevokedHostKeys=$OBJ/host_krl_plain attempt_connect "$ktype KRL w/ cert revoked" "no" \ -oRevokedHostKeys=$OBJ/host_krl_cert attempt_connect "$ktype KRL w/ CA revoked" "no" \ -oRevokedHostKeys=$OBJ/host_krl_ca attempt_connect "$ktype empty plaintext revocation" "yes" \ -oRevokedHostKeys=$OBJ/host_revoked_empty attempt_connect "$ktype plain key plaintext revocation" "no" \ -oRevokedHostKeys=$OBJ/host_revoked_plain attempt_connect "$ktype cert plaintext revocation" "no" \ -oRevokedHostKeys=$OBJ/host_revoked_cert attempt_connect "$ktype CA plaintext revocation" "no" \ -oRevokedHostKeys=$OBJ/host_revoked_ca done done # Revoked certificates with key present ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub for ktype in $PLAIN_TYPES ; do test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" done ) > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for privsep in yes no ; do for ktype in $PLAIN_TYPES ; do verbose "$tid: host ${ktype} revoked cert privsep $privsep" ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${ktype} echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub echo UsePrivilegeSeparation $privsep ) > $OBJ/sshd_proxy cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi done done # Revoked CA ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub printf '@revoked ' printf "* " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for ktype in $PLAIN_TYPES ; do verbose "$tid: host ${ktype} revoked cert" ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${ktype} echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub ) > $OBJ/sshd_proxy cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi done # Create a CA key and add it to known hosts ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert test_one() { ident=$1 result=$2 sign_opts=$3 for kt in rsa ed25519 ; do ${SSHKEYGEN} -q -s $OBJ/host_ca_key \ -I "regress host key for $USER" \ $sign_opts $OBJ/cert_host_key_${kt} || fail "couldn't sign cert_host_key_${kt}" ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${kt} echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub ) > $OBJ/sshd_proxy cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 rc=$? if [ "x$result" = "xsuccess" ] ; then if [ $rc -ne 0 ]; then fail "ssh cert connect $ident failed unexpectedly" fi else if [ $rc -eq 0 ]; then fail "ssh cert connect $ident succeeded unexpectedly" fi fi done } test_one "user-certificate" failure "-n $HOSTS" test_one "empty principals" success "-h" test_one "wrong principals" failure "-h -n foo" test_one "cert not yet valid" failure "-h -V20200101:20300101" test_one "cert expired" failure "-h -V19800101:19900101" test_one "cert valid interval" success "-h -V-1w:+2w" test_one "cert has constraints" failure "-h -Oforce-command=false" # Check downgrade of cert to raw key when no CA found for ktype in $PLAIN_TYPES ; do rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key* verbose "$tid: host ${ktype} ${v} cert downgrade to raw key" # Generate and sign a host key ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_host_key_${ktype} || \ fail "ssh-keygen of cert_host_key_${ktype} failed" ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || fail "couldn't sign cert_host_key_${ktype}" ( printf "$HOSTS " cat $OBJ/cert_host_key_${ktype}.pub ) > $OBJ/known_hosts-cert ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${ktype} echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub ) > $OBJ/sshd_proxy ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi done # Wrong certificate ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for kt in $PLAIN_TYPES ; do rm -f $OBJ/cert_host_key* # Self-sign key ${SSHKEYGEN} -q -N '' -t ${kt} \ -f $OBJ/cert_host_key_${kt} || \ fail "ssh-keygen of cert_host_key_${kt} failed" ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${kt} || fail "couldn't sign cert_host_key_${kt}" verbose "$tid: host ${kt} connect wrong cert" ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${kt} echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub ) > $OBJ/sshd_proxy cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect $ident succeeded unexpectedly" fi done rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/cert_host_key* openssh-7.2p2/regress/cert-userkey.sh010064400017500001750000000260751267006270000161140ustar00djmdjm# $OpenBSD: cert-userkey.sh,v 1.14 2015/07/10 06:23:25 markus Exp $ # Placed in the Public Domain. tid="certified user keys" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` kname() { n=`echo "$1" | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/'` echo "$n*,ssh-rsa*,ssh-ed25519*" } # Create a CA key ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ fail "ssh-keygen of user_ca_key failed" # Generate and sign user keys for ktype in $PLAIN_TYPES ; do verbose "$tid: sign user ${ktype} cert" ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_user_key_${ktype} || \ fail "ssh-keygen of cert_user_key_${ktype} failed" ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" done # Test explicitly-specified principals for ktype in $PLAIN_TYPES ; do t=$(kname $ktype) for privsep in yes no ; do _prefix="${ktype} privsep $privsep" # Setup for AuthorizedPrincipalsFile rm -f $OBJ/authorized_keys_$USER ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" echo "AuthorizedPrincipalsFile " \ "$OBJ/authorized_principals_%u" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "PubkeyAcceptedKeyTypes ${t}" ) > $OBJ/sshd_proxy ( cat $OBJ/ssh_proxy_bak echo "PubkeyAcceptedKeyTypes ${t}" ) > $OBJ/ssh_proxy # Missing authorized_principals verbose "$tid: ${_prefix} missing authorized_principals" rm -f $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Empty authorized_principals verbose "$tid: ${_prefix} empty authorized_principals" echo > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Wrong authorized_principals verbose "$tid: ${_prefix} wrong authorized_principals" echo gregorsamsa > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Correct authorized_principals verbose "$tid: ${_prefix} correct authorized_principals" echo mekmitasdigoat > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi # authorized_principals with bad key option verbose "$tid: ${_prefix} authorized_principals bad key opt" echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # authorized_principals with command=false verbose "$tid: ${_prefix} authorized_principals command=false" echo 'command="false" mekmitasdigoat' > \ $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # authorized_principals with command=true verbose "$tid: ${_prefix} authorized_principals command=true" echo 'command="true" mekmitasdigoat' > \ $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi # Setup for principals= key option rm -f $OBJ/authorized_principals_$USER ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" echo "PubkeyAcceptedKeyTypes ${t}" ) > $OBJ/sshd_proxy ( cat $OBJ/ssh_proxy_bak echo "PubkeyAcceptedKeyTypes ${t}" ) > $OBJ/ssh_proxy # Wrong principals list verbose "$tid: ${_prefix} wrong principals key option" ( printf 'cert-authority,principals="gregorsamsa" ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Correct principals list verbose "$tid: ${_prefix} correct principals key option" ( printf 'cert-authority,principals="mekmitasdigoat" ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi done done basic_tests() { auth=$1 if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys ( printf 'cert-authority ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER else echo > $OBJ/authorized_keys_$USER extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi for ktype in $PLAIN_TYPES ; do t=$(kname $ktype) for privsep in yes no ; do _prefix="${ktype} privsep $privsep $auth" # Simple connect verbose "$tid: ${_prefix} connect" ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" echo "PubkeyAcceptedKeyTypes ${t}" echo "$extra_sshd" ) > $OBJ/sshd_proxy ( cat $OBJ/ssh_proxy_bak echo "PubkeyAcceptedKeyTypes ${t}" ) > $OBJ/ssh_proxy ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi # Revoked keys verbose "$tid: ${_prefix} revoked key" ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" echo "RevokedKeys $OBJ/cert_user_key_revoked" echo "PubkeyAcceptedKeyTypes ${t}" echo "$extra_sshd" ) > $OBJ/sshd_proxy cp $OBJ/cert_user_key_${ktype}.pub \ $OBJ/cert_user_key_revoked ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpecedly" fi verbose "$tid: ${_prefix} revoked via KRL" rm $OBJ/cert_user_key_revoked ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ $OBJ/cert_user_key_${ktype}.pub ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpecedly" fi verbose "$tid: ${_prefix} empty KRL" ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi done # Revoked CA verbose "$tid: ${ktype} $auth revoked CA key" ( cat $OBJ/sshd_proxy_bak echo "RevokedKeys $OBJ/user_ca_key.pub" echo "PubkeyAcceptedKeyTypes ${t}" echo "$extra_sshd" ) > $OBJ/sshd_proxy ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpecedly" fi done verbose "$tid: $auth CA does not authenticate" ( cat $OBJ/sshd_proxy_bak echo "PubkeyAcceptedKeyTypes ${t}" echo "$extra_sshd" ) > $OBJ/sshd_proxy verbose "$tid: ensure CA key does not authenticate user" ${SSH} -2i $OBJ/user_ca_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect with CA key succeeded unexpectedly" fi } basic_tests authorized_keys basic_tests TrustedUserCAKeys test_one() { ident=$1 result=$2 sign_opts=$3 auth_choice=$4 auth_opt=$5 if test "x$auth_choice" = "x" ; then auth_choice="authorized_keys TrustedUserCAKeys" fi for auth in $auth_choice ; do for ktype in rsa ed25519 ; do cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys ( printf "cert-authority${auth_opt} " cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER else echo > $OBJ/authorized_keys_$USER echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ >> $OBJ/sshd_proxy echo "PubkeyAcceptedKeyTypes ${t}*" \ >> $OBJ/sshd_proxy if test "x$auth_opt" != "x" ; then echo $auth_opt >> $OBJ/sshd_proxy fi fi verbose "$tid: $ident auth $auth expect $result $ktype" ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ -I "regress user key for $USER" \ $sign_opts $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" ${SSH} -2i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 rc=$? if [ "x$result" = "xsuccess" ] ; then if [ $rc -ne 0 ]; then fail "$ident failed unexpectedly" fi else if [ $rc -eq 0 ]; then fail "$ident succeeded unexpectedly" fi fi done done } test_one "correct principal" success "-n ${USER}" test_one "host-certificate" failure "-n ${USER} -h" test_one "wrong principals" failure "-n foo" test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" test_one "cert expired" failure "-n ${USER} -V19800101:19900101" test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" test_one "force-command" failure "-n ${USER} -Oforce-command=false" # Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals test_one "empty principals" success "" authorized_keys test_one "empty principals" failure "" TrustedUserCAKeys # Check explicitly-specified principals: an empty principals list in the cert # should always be refused. # AuthorizedPrincipalsFile rm -f $OBJ/authorized_keys_$USER echo mekmitasdigoat > $OBJ/authorized_principals_$USER test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" test_one "AuthorizedPrincipalsFile no principals" failure "" \ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" # principals= key option rm -f $OBJ/authorized_principals_$USER test_one "principals key option principals" success "-n mekmitasdigoat" \ authorized_keys ',principals="mekmitasdigoat"' test_one "principals key option no principals" failure "" \ authorized_keys ',principals="mekmitasdigoat"' # Wrong certificate cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy for ktype in $PLAIN_TYPES ; do t=$(kname $ktype) # Self-sign ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \ "regress user key for $USER" \ -n $USER $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" verbose "$tid: user ${ktype} connect wrong cert" ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect $ident succeeded unexpectedly" fi done rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* rm -f $OBJ/authorized_principals_$USER openssh-7.2p2/regress/cfgmatch.sh010064400017500001750000000075131267006270000152420ustar00djmdjm# $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd_config match" pidfile=$OBJ/remote_pid fwdport=3301 fwd="-L $fwdport:127.0.0.1:$PORT" echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_config echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy start_client() { rm -f $pidfile ${SSH} -q -$p $fwd "$@" somehost \ exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \ >>$TEST_REGRESS_LOGFILE 2>&1 & client_pid=$! # Wait for remote end n=0 while test ! -f $pidfile ; do sleep 1 n=`expr $n + 1` if test $n -gt 60; then kill $client_pid fatal "timeout waiting for background ssh" fi done } stop_client() { pid=`cat $pidfile` if [ ! -z "$pid" ]; then kill $pid fi wait } cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_config echo "Match Address 127.0.0.1" >>$OBJ/sshd_config echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_config grep -v AuthorizedKeysFile $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy echo "AuthorizedKeysFile /dev/null" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_proxy echo "Match user $USER" >>$OBJ/sshd_proxy echo "AuthorizedKeysFile /dev/null $OBJ/authorized_keys_%u" >>$OBJ/sshd_proxy echo "Match Address 127.0.0.1" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_proxy start_sshd #set -x # Test Match + PermitOpen in sshd_config. This should be permitted for p in ${SSH_PROTOCOLS}; do trace "match permitopen localhost proto $p" start_client -F $OBJ/ssh_config ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ fail "match permitopen permit proto $p" stop_client done # Same but from different source. This should not be permitted for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ fail "match permitopen deny proto $p" stop_client done # Retry previous with key option, should also be denied. cp /dev/null $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER done for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ fail "match permitopen deny w/key opt proto $p" stop_client done # Test both sshd_config and key options permitting the same dst/port pair. # Should be permitted. for p in ${SSH_PROTOCOLS}; do trace "match permitopen localhost proto $p" start_client -F $OBJ/ssh_config ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ fail "match permitopen permit proto $p" stop_client done cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy echo "Match User $USER" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a Match overrides a PermitOpen in the global section for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ fail "match override permitopen proto $p" stop_client done cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy echo "Match User NoSuchUser" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a rule that doesn't match doesn't override, plus test a # PermitOpen entry that's not at the start of the list for p in ${SSH_PROTOCOLS}; do trace "nomatch permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ fail "nomatch override permitopen proto $p" stop_client done openssh-7.2p2/regress/cfgparse.sh010064400017500001750000000042321267006270000152530ustar00djmdjm# $OpenBSD: cfgparse.sh,v 1.5 2015/05/29 03:05:13 djm Exp $ # Placed in the Public Domain. tid="config parse" # This is a reasonable proxy for IPv6 support. if ! config_defined HAVE_STRUCT_IN6_ADDR ; then SKIP_IPV6=yes fi # We need to use the keys generated for the regression test because sshd -T # will fail if we're not running with SUDO (no permissions for real keys) or # if we are # running tests on a system that has never had sshd installed # (keys won't exist). grep "HostKey " $OBJ/sshd_config > $OBJ/sshd_config_minimal SSHD_KEYS="`cat $OBJ/sshd_config_minimal`" verbose "reparse minimal config" ($SUDO ${SSHD} -T -f $OBJ/sshd_config_minimal >$OBJ/sshd_config.1 && $SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse minimal config" verbose "reparse regress config" ($SUDO ${SSHD} -T -f $OBJ/sshd_config >$OBJ/sshd_config.1 && $SUDO ${SSHD} -T -f $OBJ/sshd_config.1 >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.1 $OBJ/sshd_config.2) || fail "reparse regress config" verbose "listenaddress order" # expected output cat > $OBJ/sshd_config.0 <> $OBJ/sshd_config.0 < $OBJ/sshd_config.1 <> $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 1" # test 2: listenaddress first cat > $OBJ/sshd_config.1 <> $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 2" # cleanup rm -f $OBJ/sshd_config.[012] openssh-7.2p2/regress/check-perm.c010064400017500001750000000105231267006270000153070ustar00djmdjm/* * Placed in the public domain */ /* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ #include "includes.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBGEN_H #include #endif static void fatal(const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); exit(1); } /* Based on session.c. NB. keep tests in sync */ static void safely_chroot(const char *path, uid_t uid) { const char *cp; char component[PATH_MAX]; struct stat st; if (*path != '/') fatal("chroot path does not begin at root"); if (strlen(path) >= sizeof(component)) fatal("chroot path too long"); /* * Descend the path, checking that each component is a * root-owned directory with strict permissions. */ for (cp = path; cp != NULL;) { if ((cp = strchr(cp, '/')) == NULL) strlcpy(component, path, sizeof(component)); else { cp++; memcpy(component, path, cp - path); component[cp - path] = '\0'; } /* debug3("%s: checking '%s'", __func__, component); */ if (stat(component, &st) != 0) fatal("%s: stat(\"%s\"): %s", __func__, component, strerror(errno)); if (st.st_uid != 0 || (st.st_mode & 022) != 0) fatal("bad ownership or modes for chroot " "directory %s\"%s\"", cp == NULL ? "" : "component ", component); if (!S_ISDIR(st.st_mode)) fatal("chroot path %s\"%s\" is not a directory", cp == NULL ? "" : "component ", component); } if (chdir(path) == -1) fatal("Unable to chdir to chroot path \"%s\": " "%s", path, strerror(errno)); } /* from platform.c */ int platform_sys_dir_uid(uid_t uid) { if (uid == 0) return 1; #ifdef PLATFORM_SYS_DIR_UID if (uid == PLATFORM_SYS_DIR_UID) return 1; #endif return 0; } /* from auth.c */ int auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, uid_t uid, char *err, size_t errlen) { char buf[PATH_MAX], homedir[PATH_MAX]; char *cp; int comparehome = 0; struct stat st; if (realpath(name, buf) == NULL) { snprintf(err, errlen, "realpath %s failed: %s", name, strerror(errno)); return -1; } if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) comparehome = 1; if (!S_ISREG(stp->st_mode)) { snprintf(err, errlen, "%s is not a regular file", buf); return -1; } if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || (stp->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)); if (stat(buf, &st) < 0 || (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || (st.st_mode & 022) != 0) { snprintf(err, errlen, "bad ownership or modes for directory %s", buf); return -1; } /* If are past the homedir then we can stop */ if (comparehome && strcmp(homedir, buf) == 0) 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; } static void usage(void) { fprintf(stderr, "check-perm -m [chroot | keys-command] [path]\n"); exit(1); } int main(int argc, char **argv) { const char *path = "."; char errmsg[256]; int ch, mode = -1; extern char *optarg; extern int optind; struct stat st; while ((ch = getopt(argc, argv, "hm:")) != -1) { switch (ch) { case 'm': if (strcasecmp(optarg, "chroot") == 0) mode = 1; else if (strcasecmp(optarg, "keys-command") == 0) mode = 2; else { fprintf(stderr, "Invalid -m option\n"), usage(); } break; default: usage(); } } argc -= optind; argv += optind; if (argc > 1) usage(); else if (argc == 1) path = argv[0]; if (mode == 1) safely_chroot(path, getuid()); else if (mode == 2) { if (stat(path, &st) < 0) fatal("Could not stat %s: %s", path, strerror(errno)); if (auth_secure_path(path, &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) fatal("Unsafe %s: %s", path, errmsg); } else { fprintf(stderr, "Invalid mode\n"); usage(); } return 0; } openssh-7.2p2/regress/cipher-speed.sh010064400017500001750000000022671267006270000160370ustar00djmdjm# $OpenBSD: cipher-speed.sh,v 1.13 2015/03/24 20:22:17 markus Exp $ # Placed in the Public Domain. tid="cipher speed" getbytes () { sed -n -e '/transferred/s/.*secs (\(.* bytes.sec\).*/\1/p' \ -e '/copied/s/.*s, \(.* MB.s\).*/\1/p' } tries="1 2" for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do trace "proto 2 cipher $c mac $m" for x in $tries; do printf "%-60s" "$c/$m:" ( ${SSH} -o 'compression no' \ -F $OBJ/ssh_proxy -2 -m $m -c $c somehost \ exec sh -c \'"dd of=/dev/null obs=32k"\' \ < ${DATA} ) 2>&1 | getbytes if [ $? -ne 0 ]; then fail "ssh -2 failed with mac $m cipher $c" fi done # No point trying all MACs for AEAD ciphers since they are ignored. if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then break fi n=`expr $n + 1` done; done if ssh_version 1; then ciphers="3des blowfish" else ciphers="" fi for c in $ciphers; do trace "proto 1 cipher $c" for x in $tries; do printf "%-60s" "$c:" ( ${SSH} -o 'compression no' \ -F $OBJ/ssh_proxy -1 -c $c somehost \ exec sh -c \'"dd of=/dev/null obs=32k"\' \ < ${DATA} ) 2>&1 | getbytes if [ $? -ne 0 ]; then fail "ssh -1 failed with cipher $c" fi done done openssh-7.2p2/regress/conch-ciphers.sh010064400017500001750000000014341267006270000162070ustar00djmdjm# $OpenBSD: conch-ciphers.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="conch ciphers" if test "x$REGRESS_INTEROP_CONCH" != "xyes" ; then echo "conch interop tests not enabled" exit 0 fi start_sshd for c in aes256-ctr aes256-cbc aes192-ctr aes192-cbc aes128-ctr aes128-cbc \ cast128-cbc blowfish 3des-cbc ; do verbose "$tid: cipher $c" rm -f ${COPY} # XXX the 2nd "cat" seems to be needed because of buggy FD handling # in conch ${CONCH} --identity $OBJ/rsa --port $PORT --user $USER -e none \ --known-hosts $OBJ/known_hosts --notty --noagent --nox11 -n \ 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" done rm -f ${COPY} openssh-7.2p2/regress/connect.sh010064400017500001750000000004451267006270000151140ustar00djmdjm# $OpenBSD: connect.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple connect" start_sshd for p in ${SSH_PROTOCOLS}; do ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed" fi done openssh-7.2p2/regress/connect-privsep.sh010064400017500001750000000021311267006270000165740ustar00djmdjm# $OpenBSD: connect-privsep.sh,v 1.6 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="proxy connect with privsep" cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then fail "ssh privsep+proxyconnect protocol $p failed" fi done cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then # XXX replace this with fail once sandbox has stabilised warn "ssh privsep/sandbox+proxyconnect protocol $p failed" fi done # Because sandbox is sensitive to changes in libc, especially malloc, retest # with every malloc.conf option (and none). for m in '' A F G H J P R S X '<' '>'; do for p in ${SSH_PROTOCOLS}; do env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" fi done done openssh-7.2p2/regress/dhgex.sh010064400017500001750000000030051267006270000145550ustar00djmdjm# $OpenBSD: dhgex.sh,v 1.3 2015/10/23 02:22:01 dtucker Exp $ # Placed in the Public Domain. tid="dhgex" LOG=${TEST_SSH_LOGFILE} rm -f ${LOG} cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange` ssh_test_dhgex() { bits="$1"; shift cipher="$1"; shift kex="$1"; shift cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "KexAlgorithms=$kex" >> $OBJ/sshd_proxy echo "Ciphers=$cipher" >> $OBJ/sshd_proxy rm -f ${LOG} opts="-oKexAlgorithms=$kex -oCiphers=$cipher" min=2048 max=8192 groupsz="$min<$bits<$max" verbose "$tid bits $bits $kex $cipher" ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "ssh failed ($@)" fi # check what we request grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null if [ $? != 0 ]; then got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}` fail "$tid unexpected GEX sizes, expected $groupsz, got $got" fi # check what we got (depends on contents of system moduli file) gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`" if [ "$gotbits" -lt "$bits" ]; then fatal "$tid expected $bits bit group, got $gotbits" fi } check() { bits="$1"; shift for c in $@; do for k in $kexs; do ssh_test_dhgex $bits $c $k done done } #check 2048 3des-cbc check 3072 `${SSH} -Q cipher | grep 128` check 3072 arcfour blowfish-cbc check 7680 `${SSH} -Q cipher | grep 192` check 8192 `${SSH} -Q cipher | grep 256` check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com openssh-7.2p2/regress/dsa_ssh2.prv010064400017500001750000000015371267006270000153710ustar00djmdjm---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- Subject: ssh-keygen test Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1 kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6 75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A== ---- END SSH2 ENCRYPTED PRIVATE KEY ---- openssh-7.2p2/regress/dsa_ssh2.pub010064400017500001750000000013341267006270000153430ustar00djmdjm---- BEGIN SSH2 PUBLIC KEY ---- Subject: ssh-keygen test Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8 NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo 0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1 ixaVivLt8RgTwGF99uI= ---- END SSH2 PUBLIC KEY ---- openssh-7.2p2/regress/dynamic-forward.sh010064400017500001750000000030331267006270000165450ustar00djmdjm# $OpenBSD: dynamic-forward.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="dynamic forwarding" FWDPORT=`expr $PORT + 1` if have_prog nc && nc -h 2>&1 | grep "proxy address" >/dev/null; then proxycmd="nc -x 127.0.0.1:$FWDPORT -X" elif have_prog connect; then proxycmd="connect -S 127.0.0.1:$FWDPORT -" else echo "skipped (no suitable ProxyCommand found)" exit 0 fi trace "will use ProxyCommand $proxycmd" start_sshd for p in ${SSH_PROTOCOLS}; do n=0 error="1" trace "start dynamic forwarding, fork to background" while [ "$error" -ne 0 -a "$n" -lt 3 ]; do n=`expr $n + 1` ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q \ -oExitOnForwardFailure=yes somehost exec sh -c \ \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\' error=$? if [ "$error" -ne 0 ]; then trace "forward failed proto $p attempt $n err $error" sleep $n fi done if [ "$error" -ne 0 ]; then fatal "failed to start dynamic forwarding proto $p" fi for s in 4 5; do for h in 127.0.0.1 localhost; do trace "testing ssh protocol $p socks version $s host $h" ${SSH} -F $OBJ/ssh_config \ -o "ProxyCommand ${proxycmd}${s} $h $PORT" \ somehost cat $DATA > $OBJ/ls.copy test -f $OBJ/ls.copy || fail "failed copy $DATA" cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" done done if [ -f $OBJ/remote_pid ]; then remote=`cat $OBJ/remote_pid` trace "terminate remote shell, pid $remote" if [ $remote -gt 1 ]; then kill -HUP $remote fi else fail "no pid file: $OBJ/remote_pid" fi done openssh-7.2p2/regress/envpass.sh010064400017500001750000000030531267006270000151400ustar00djmdjm# $OpenBSD: envpass.sh,v 1.4 2005/03/04 08:48:46 djm Exp $ # Placed in the Public Domain. tid="environment passing" # NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST) # Prepare a custom config to test for a configuration parsing bug fixed in 4.0 cat << EOF > $OBJ/ssh_proxy_envpass Host test-sendenv-confparse-bug SendEnv * EOF cat $OBJ/ssh_proxy >> $OBJ/ssh_proxy_envpass trace "pass env, don't accept" verbose "test $tid: pass env, don't accept" _TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy_envpass otherhost \ sh << 'EOF' test -z "$_TEST_ENV" EOF r=$? if [ $r -ne 0 ]; then fail "environment found" fi trace "don't pass env, accept" verbose "test $tid: don't pass env, accept" _XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -F $OBJ/ssh_proxy_envpass otherhost \ sh << 'EOF' test -z "$_XXX_TEST_A" && test -z "$_XXX_TEST_B" EOF r=$? if [ $r -ne 0 ]; then fail "environment found" fi trace "pass single env, accept single env" verbose "test $tid: pass single env, accept single env" _XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy_envpass \ otherhost sh << 'EOF' test X"$_XXX_TEST" = X"blah" EOF r=$? if [ $r -ne 0 ]; then fail "environment not found" fi trace "pass multiple env, accept multiple env" verbose "test $tid: pass multiple env, accept multiple env" _XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \ -F $OBJ/ssh_proxy_envpass otherhost \ sh << 'EOF' test X"$_XXX_TEST_A" = X"1" -a X"$_XXX_TEST_B" = X"2" EOF r=$? if [ $r -ne 0 ]; then fail "environment not found" fi rm -f $OBJ/ssh_proxy_envpass openssh-7.2p2/regress/exit-status.sh010064400017500001750000000012451267006270000157540ustar00djmdjm# $OpenBSD: exit-status.sh,v 1.7 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="remote exit status" for p in ${SSH_PROTOCOLS}; do for s in 0 1 4 5 44; do trace "proto $p status $s" verbose "test $tid: proto $p status $s" ${SSH} -$p -F $OBJ/ssh_proxy otherhost exit $s r=$? if [ $r -ne $s ]; then fail "exit code mismatch for protocol $p: $r != $s" fi # same with early close of stdout/err ${SSH} -$p -F $OBJ/ssh_proxy -n otherhost \ exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' r=$? if [ $r -ne $s ]; then fail "exit code (with sleep) mismatch for protocol $p: $r != $s" fi done done openssh-7.2p2/regress/forcecommand.sh010064400017500001750000000024531267006270000161210ustar00djmdjm# $OpenBSD: forcecommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="forced command" cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp /dev/null $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do printf 'command="true" ' >>$OBJ/authorized_keys_$USER cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER done for p in ${SSH_PROTOCOLS}; do trace "forced command in key option proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" done cp /dev/null $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do printf 'command="false" ' >> $OBJ/authorized_keys_$USER cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER done cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "ForceCommand true" >> $OBJ/sshd_proxy for p in ${SSH_PROTOCOLS}; do trace "forced command in sshd_config overrides key option proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" done cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "ForceCommand false" >> $OBJ/sshd_proxy echo "Match User $USER" >> $OBJ/sshd_proxy echo " ForceCommand true" >> $OBJ/sshd_proxy for p in ${SSH_PROTOCOLS}; do trace "forced command with match proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" done openssh-7.2p2/regress/forward-control.sh010064400017500001750000000126331267006270000166070ustar00djmdjm# $OpenBSD: forward-control.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd control of local and remote forwarding" LFWD_PORT=3320 RFWD_PORT=3321 CTL=$OBJ/ctl-sock READY=$OBJ/ready wait_for_file_to_appear() { _path=$1 _n=0 while test ! -f $_path ; do test $_n -eq 1 && trace "waiting for $_path to appear" _n=`expr $_n + 1` test $_n -ge 20 && return 1 sleep 1 done return 0 } wait_for_process_to_exit() { _pid=$1 _n=0 while kill -0 $_pid 2>/dev/null ; do test $_n -eq 1 && trace "waiting for $_pid to exit" _n=`expr $_n + 1` test $_n -ge 20 && return 1 sleep 1 done return 0 } # usage: check_lfwd protocol Y|N message check_lfwd() { _proto=$1 _expected=$2 _message=$3 rm -f $READY ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ -L$LFWD_PORT:127.0.0.1:$PORT \ -o ExitOnForwardFailure=yes \ -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ >/dev/null 2>&1 & _sshpid=$! wait_for_file_to_appear $READY || \ fatal "check_lfwd ssh fail: $_message" ${SSH} -F $OBJ/ssh_config -p $LFWD_PORT \ -oConnectionAttempts=4 host true >/dev/null 2>&1 _result=$? kill $_sshpid `cat $READY` 2>/dev/null wait_for_process_to_exit $_sshpid if test "x$_expected" = "xY" -a $_result -ne 0 ; then fail "check_lfwd failed (expecting success): $_message" elif test "x$_expected" = "xN" -a $_result -eq 0 ; then fail "check_lfwd succeeded (expecting failure): $_message" elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then fatal "check_lfwd invalid argument \"$_expected\"" else verbose "check_lfwd done (expecting $_expected): $_message" fi } # usage: check_rfwd protocol Y|N message check_rfwd() { _proto=$1 _expected=$2 _message=$3 rm -f $READY ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ -R$RFWD_PORT:127.0.0.1:$PORT \ -o ExitOnForwardFailure=yes \ -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ >/dev/null 2>&1 & _sshpid=$! wait_for_file_to_appear $READY _result=$? if test $_result -eq 0 ; then ${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \ -oConnectionAttempts=4 host true >/dev/null 2>&1 _result=$? kill $_sshpid `cat $READY` 2>/dev/null wait_for_process_to_exit $_sshpid fi if test "x$_expected" = "xY" -a $_result -ne 0 ; then fail "check_rfwd failed (expecting success): $_message" elif test "x$_expected" = "xN" -a $_result -eq 0 ; then fail "check_rfwd succeeded (expecting failure): $_message" elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then fatal "check_rfwd invalid argument \"$_expected\"" else verbose "check_rfwd done (expecting $_expected): $_message" fi } start_sshd cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak # Sanity check: ensure the default config allows forwarding for p in ${SSH_PROTOCOLS} ; do check_lfwd $p Y "proto $p, default configuration" check_rfwd $p Y "proto $p, default configuration" done # Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N all_tests() { _tcpfwd=$1 _plain_lfwd=$2 _plain_rfwd=$3 _nopermit_lfwd=$4 _nopermit_rfwd=$5 _permit_lfwd=$6 _permit_rfwd=$7 _badfwd=127.0.0.1:22 _goodfwd=127.0.0.1:${PORT} for _proto in ${SSH_PROTOCOLS} ; do cp ${OBJ}/authorized_keys_${USER}.bak \ ${OBJ}/authorized_keys_${USER} _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" # No PermitOpen ( cat ${OBJ}/sshd_proxy.bak ; echo "AllowTcpForwarding $_tcpfwd" ) \ > ${OBJ}/sshd_proxy check_lfwd $_proto $_plain_lfwd "$_prefix" check_rfwd $_proto $_plain_rfwd "$_prefix" # PermitOpen via sshd_config that doesn't match ( cat ${OBJ}/sshd_proxy.bak ; echo "AllowTcpForwarding $_tcpfwd" ; echo "PermitOpen $_badfwd" ) \ > ${OBJ}/sshd_proxy check_lfwd $_proto $_nopermit_lfwd "$_prefix, !PermitOpen" check_rfwd $_proto $_nopermit_rfwd "$_prefix, !PermitOpen" # PermitOpen via sshd_config that does match ( cat ${OBJ}/sshd_proxy.bak ; echo "AllowTcpForwarding $_tcpfwd" ; echo "PermitOpen $_badfwd $_goodfwd" ) \ > ${OBJ}/sshd_proxy # NB. permitopen via authorized_keys should have same # success/fail as via sshd_config # permitopen via authorized_keys that doesn't match sed "s/^/permitopen=\"$_badfwd\" /" \ < ${OBJ}/authorized_keys_${USER}.bak \ > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail" ( cat ${OBJ}/sshd_proxy.bak ; echo "AllowTcpForwarding $_tcpfwd" ) \ > ${OBJ}/sshd_proxy check_lfwd $_proto $_nopermit_lfwd "$_prefix, !permitopen" check_rfwd $_proto $_nopermit_rfwd "$_prefix, !permitopen" # permitopen via authorized_keys that does match sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \ < ${OBJ}/authorized_keys_${USER}.bak \ > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail" ( cat ${OBJ}/sshd_proxy.bak ; echo "AllowTcpForwarding $_tcpfwd" ) \ > ${OBJ}/sshd_proxy check_lfwd $_proto $_permit_lfwd "$_prefix, permitopen" check_rfwd $_proto $_permit_rfwd "$_prefix, permitopen" done } # no-permitopen mismatch-permitopen match-permitopen # AllowTcpForwarding local remote local remote local remote all_tests yes Y Y N Y Y Y all_tests local Y N N N Y N all_tests remote N Y N Y N Y all_tests no N N N N N N openssh-7.2p2/regress/forwarding.sh010064400017500001750000000101411267006270000156170ustar00djmdjm# $OpenBSD: forwarding.sh,v 1.15 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="local and remote forwarding" DATA=/bin/ls${EXEEXT} start_sshd base=33 last=$PORT fwd="" CTL=$OBJ/ctl-sock rm -f $CTL for j in 0 1 2; do for i in 0 1 2; do a=$base$j$i b=`expr $a + 50` c=$last # fwd chain: $a -> $b -> $c fwd="$fwd -L$a:127.0.0.1:$b -R$b:127.0.0.1:$c" last=$a done done for p in ${SSH_PROTOCOLS}; do q=`expr 3 - $p` if ! ssh_version $q; then q=$p fi trace "start forwarding, fork to background" ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 trace "transfer over forwarded channels and check result" ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ somehost cat ${DATA} > ${COPY} test -s ${COPY} || fail "failed copy of ${DATA}" cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" sleep 10 done for p in ${SSH_PROTOCOLS}; do for d in L R; do trace "exit on -$d forward failure, proto $p" # this one should succeed ${SSH} -$p -F $OBJ/ssh_config \ -$d ${base}01:127.0.0.1:$PORT \ -$d ${base}02:127.0.0.1:$PORT \ -$d ${base}03:127.0.0.1:$PORT \ -$d ${base}04:127.0.0.1:$PORT \ -oExitOnForwardFailure=yes somehost true if [ $? != 0 ]; then fail "connection failed, should not" else # this one should fail ${SSH} -q -$p -F $OBJ/ssh_config \ -$d ${base}01:127.0.0.1:$PORT \ -$d ${base}02:127.0.0.1:$PORT \ -$d ${base}03:127.0.0.1:$PORT \ -$d ${base}01:127.0.0.1:$PORT \ -$d ${base}04:127.0.0.1:$PORT \ -oExitOnForwardFailure=yes somehost true r=$? if [ $r != 255 ]; then fail "connection not termintated, but should ($r)" fi fi done done for p in ${SSH_PROTOCOLS}; do trace "simple clear forwarding proto $p" ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true trace "clear local forward proto $p" ${SSH} -$p -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \ -oClearAllForwardings=yes somehost sleep 10 if [ $? != 0 ]; then fail "connection failed with cleared local forwarding" else # this one should fail ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \ >>$TEST_REGRESS_LOGFILE 2>&1 && \ fail "local forwarding not cleared" fi sleep 10 trace "clear remote forward proto $p" ${SSH} -$p -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \ -oClearAllForwardings=yes somehost sleep 10 if [ $? != 0 ]; then fail "connection failed with cleared remote forwarding" else # this one should fail ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \ >>$TEST_REGRESS_LOGFILE 2>&1 && \ fail "remote forwarding not cleared" fi sleep 10 done for p in 2; do trace "stdio forwarding proto $p" cmd="${SSH} -$p -F $OBJ/ssh_config" $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \ somehost true if [ $? != 0 ]; then fail "stdio forwarding proto $p" fi done echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config for p in ${SSH_PROTOCOLS}; do trace "config file: start forwarding, fork to background" ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f somehost sleep 10 trace "config file: transfer over forwarded channels and check result" ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ somehost cat ${DATA} > ${COPY} test -s ${COPY} || fail "failed copy of ${DATA}" cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" ${SSH} -S $CTL -O exit somehost done for p in 2; do trace "transfer over chained unix domain socket forwards and check result" rm -f $OBJ/unix-[123].fwd ${SSH} -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10 ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10 ${SSH} -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10 ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10 ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \ somehost cat ${DATA} > ${COPY} test -s ${COPY} || fail "failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" #wait sleep 10 done openssh-7.2p2/regress/host-expand.sh010064400017500001750000000007241267006270000157150ustar00djmdjm# $OpenBSD: host-expand.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="expand %h and %n" echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy printf 'LocalCommand printf "%%%%s\\n" "%%n" "%%h"\n' >> $OBJ/ssh_proxy cat >$OBJ/expect <$OBJ/actual diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" done openssh-7.2p2/regress/hostkey-agent.sh010064400017500001750000000031631267006270000162450ustar00djmdjm# $OpenBSD: hostkey-agent.sh,v 1.6 2015/07/10 06:23:25 markus Exp $ # Placed in the Public Domain. tid="hostkey agent" rm -f $OBJ/agent-key.* $OBJ/ssh_proxy.orig $OBJ/known_hosts.orig trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? [ $r -ne 0 ] && fatal "could not start ssh-agent: exit code $r" grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig trace "load hostkeys" for k in `${SSH} -Q key-plain` ; do ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" ( printf 'localhost-with-alias,127.0.0.1,::1 ' cat $OBJ/agent-key.$k.pub ) >> $OBJ/known_hosts.orig ${SSHADD} $OBJ/agent-key.$k >/dev/null 2>&1 || \ fatal "couldn't load key $OBJ/agent-key.$k" echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy.orig # Remove private key so the server can't use it. rm $OBJ/agent-key.$k || fatal "couldn't rm $OBJ/agent-key.$k" done cp $OBJ/known_hosts.orig $OBJ/known_hosts unset SSH_AUTH_SOCK for ps in no yes; do for k in `${SSH} -Q key-plain` ; do verbose "key type $k privsep=$ps" cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" cp $OBJ/known_hosts.orig $OBJ/known_hosts SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` if [ $? -ne 0 ]; then fail "protocol $p privsep=$ps failed" fi if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then fail "bad SSH_CONNECTION key type $k privsep=$ps" fi done done trace "kill agent" ${SSHAGENT} -k > /dev/null openssh-7.2p2/regress/hostkey-rotate.sh010064400017500001750000000075631267006270000164550ustar00djmdjm# $OpenBSD: hostkey-rotate.sh,v 1.5 2015/09/04 04:23:10 djm Exp $ # Placed in the Public Domain. tid="hostkey rotate" # Need full names here since they are used in HostKeyAlgorithms HOSTKEY_TYPES="ecdsa-sha2-nistp256 ssh-ed25519 ssh-rsa ssh-dss" rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy rm $OBJ/known_hosts trace "prepare hostkeys" nkeys=0 all_algs="" for k in `${SSH} -Q key-plain` ; do ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig nkeys=`expr $nkeys + 1` test "x$all_algs" = "x" || all_algs="${all_algs}," all_algs="${all_algs}$k" done dossh() { # All ssh should succeed in this test ${SSH} -F $OBJ/ssh_proxy "$@" x true || fail "ssh $@ failed" } expect_nkeys() { _expected=$1 _message=$2 _n=`wc -l $OBJ/known_hosts | awk '{ print $1 }'` || fatal "wc failed" [ "x$_n" = "x$_expected" ] || fail "$_message (got $_n wanted $_expected)" } check_key_present() { _type=$1 _kfile=$2 test "x$_kfile" = "x" && _kfile="$OBJ/hkr.${_type}.pub" _kpub=`awk "/$_type /"' { print $2 }' < $_kfile` || \ fatal "awk failed" fgrep "$_kpub" $OBJ/known_hosts > /dev/null } cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy # Connect to sshd with StrictHostkeyChecking=no verbose "learn hostkey with StrictHostKeyChecking=no" >$OBJ/known_hosts dossh -oHostKeyAlgorithms=ssh-ed25519 -oStrictHostKeyChecking=no # Verify no additional keys learned expect_nkeys 1 "unstrict connect keys" check_key_present ssh-ed25519 || fail "unstrict didn't learn key" # Connect to sshd as usual verbose "learn additional hostkeys" dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$all_algs # Check that other keys learned expect_nkeys $nkeys "learn hostkeys" check_key_present ssh-rsa || fail "didn't learn keys" # Check each key type for k in `${SSH} -Q key-plain` ; do verbose "learn additional hostkeys, type=$k" dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs expect_nkeys $nkeys "learn hostkeys $k" check_key_present $k || fail "didn't learn $k" done # Change one hostkey (non primary) and relearn verbose "learn changed non-primary hostkey" mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old rm -f $OBJ/hkr.ssh-rsa ${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa -N '' || fatal "ssh-keygen $k" dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$all_algs # Check that the key was replaced expect_nkeys $nkeys "learn hostkeys" check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" check_key_present ssh-rsa || fail "didn't learn changed key" # Add new hostkey (primary type) to sshd and connect verbose "learn new primary hostkey" ${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa-new -N '' || fatal "ssh-keygen $k" ( cat $OBJ/sshd_proxy.orig ; echo HostKey $OBJ/hkr.ssh-rsa-new ) \ > $OBJ/sshd_proxy # Check new hostkey added dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs expect_nkeys `expr $nkeys + 1` "learn hostkeys" check_key_present ssh-rsa || fail "current key missing" check_key_present ssh-rsa $OBJ/hkr.ssh-rsa-new.pub || fail "new key missing" # Remove old hostkey (primary type) from sshd verbose "rotate primary hostkey" cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old mv $OBJ/hkr.ssh-rsa-new.pub $OBJ/hkr.ssh-rsa.pub mv $OBJ/hkr.ssh-rsa-new $OBJ/hkr.ssh-rsa # Check old hostkey removed dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs expect_nkeys $nkeys "learn hostkeys" check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" check_key_present ssh-rsa || fail "didn't learn changed key" # Connect again, forcing rotated key verbose "check rotate primary hostkey" dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa expect_nkeys 1 "learn hostkeys" check_key_present ssh-rsa || fail "didn't learn changed key" openssh-7.2p2/regress/integrity.sh010064400017500001750000000045451267006270000155060ustar00djmdjm# $OpenBSD: integrity.sh,v 1.16 2015/03/24 20:22:17 markus Exp $ # Placed in the Public Domain. tid="integrity" cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak # start at byte 2900 (i.e. after kex) and corrupt at different offsets # XXX the test hangs if we modify the low bytes of the packet length # XXX and ssh tries to read... tries=10 startoffset=2900 macs=`${SSH} -Q mac` # The following are not MACs, but ciphers with integrated integrity. They are # handled specially below. macs="$macs `${SSH} -Q cipher-auth`" # avoid DH group exchange as the extra traffic makes it harder to get the # offset into the stream right. echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \ >> $OBJ/ssh_proxy # sshd-command for proxy (see test-exec.sh) cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" for m in $macs; do trace "test $tid: mac $m" elen=0 epad=0 emac=0 ecnt=0 skip=0 for off in `jot $tries $startoffset`; do skip=`expr $skip - 1` if [ $skip -gt 0 ]; then # avoid modifying the high bytes of the length continue fi cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy # modify output from sshd at offset $off pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1" if ${SSH} -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then echo "Ciphers=$m" >> $OBJ/sshd_proxy macopt="-c $m" else echo "Ciphers=aes128-ctr" >> $OBJ/sshd_proxy echo "MACs=$m" >> $OBJ/sshd_proxy macopt="-m $m -c aes128-ctr" fi verbose "test $tid: $m @$off" ${SSH} $macopt -2F $OBJ/ssh_proxy -o "$pxy" \ -oServerAliveInterval=1 -oServerAliveCountMax=30 \ 999.999.999.999 'printf "%4096s" " "' >/dev/null if [ $? -eq 0 ]; then fail "ssh -m $m succeeds with bit-flip at $off" fi ecnt=`expr $ecnt + 1` out=$(tail -2 $TEST_SSH_LOGFILE | egrep -v "^debug" | \ tr -s '\r\n' '.') case "$out" in Bad?packet*) elen=`expr $elen + 1`; skip=3;; Corrupted?MAC* | *message?authentication?code?incorrect*) emac=`expr $emac + 1`; skip=0;; padding*) epad=`expr $epad + 1`; skip=0;; *) fail "unexpected error mac $m at $off: $out";; esac done verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen" if [ $emac -eq 0 ]; then fail "$m: no mac errors" fi expect=`expr $ecnt - $epad - $elen` if [ $emac -ne $expect ]; then fail "$m: expected $expect mac errors, got $emac" fi done openssh-7.2p2/regress/kextype.sh010064400017500001750000000011131267006270000151450ustar00djmdjm# $OpenBSD: kextype.sh,v 1.6 2015/03/24 20:19:15 markus Exp $ # Placed in the Public Domain. tid="login with different key exchange algorithms" TIME=/usr/bin/time cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak # Make server accept all key exchanges. ALLKEX=`${SSH} -Q kex` KEXOPT=`echo $ALLKEX | tr ' ' ,` echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy tries="1 2 3 4" for k in `${SSH} -Q kex`; do verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true if [ $? -ne 0 ]; then fail "ssh kex $k" fi done done openssh-7.2p2/regress/key-options.sh010064400017500001750000000036511267006270000157460ustar00djmdjm# $OpenBSD: key-options.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="key options" origkeys="$OBJ/authkeys_orig" authkeys="$OBJ/authorized_keys_${USER}" cp $authkeys $origkeys # Test command= forced command for p in ${SSH_PROTOCOLS}; do for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do sed "s/.*/$c &/" $origkeys >$authkeys verbose "key option proto $p $c" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost echo foo` if [ "$r" = "foo" ]; then fail "key option forced command not restricted" fi if [ "$r" != "bar" ]; then fail "key option forced command not executed" fi done done # Test no-pty sed 's/.*/no-pty &/' $origkeys >$authkeys for p in ${SSH_PROTOCOLS}; do verbose "key option proto $p no-pty" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` if [ -f "$r" ]; then fail "key option failed proto $p no-pty (pty $r)" fi done # Test environment= echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys for p in ${SSH_PROTOCOLS}; do verbose "key option proto $p environment" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` if [ "$r" != "bar" ]; then fail "key option environment not set" fi done # Test from= restriction start_sshd for p in ${SSH_PROTOCOLS}; do for f in 127.0.0.1 '127.0.0.0\/8'; do cat $origkeys >$authkeys ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "key option proto $p failed without restriction" fi sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys from=`head -1 $authkeys | cut -f1 -d ' '` verbose "key option proto $p $from" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo true'` if [ "$r" = "true" ]; then fail "key option proto $p $from not restricted" fi r=`${SSH} -$p -q -F $OBJ/ssh_config somehost 'echo true'` if [ "$r" != "true" ]; then fail "key option proto $p $from not allowed but should be" fi done done rm -f "$origkeys" openssh-7.2p2/regress/keygen-change.sh010064400017500001750000000011771267006270000161730ustar00djmdjm# $OpenBSD: keygen-change.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="change passphrase for key" S1="secret1" S2="2secret" KEYTYPES=`${SSH} -Q key-plain` if ssh_version 1; then KEYTYPES="${KEYTYPES} rsa1" fi for t in $KEYTYPES; do # generate user key for agent trace "generating $t key" rm -f $OBJ/$t-key ${SSHKEYGEN} -q -N ${S1} -t $t -f $OBJ/$t-key if [ $? -eq 0 ]; then ${SSHKEYGEN} -p -P ${S1} -N ${S2} -f $OBJ/$t-key > /dev/null if [ $? -ne 0 ]; then fail "ssh-keygen -p failed for $t-key" fi else fail "ssh-keygen for $t-key failed" fi rm -f $OBJ/$t-key $OBJ/$t-key.pub done openssh-7.2p2/regress/keygen-convert.sh010064400017500001750000000021271267006270000164220ustar00djmdjm# $OpenBSD: keygen-convert.sh,v 1.1 2009/11/09 04:20:04 dtucker Exp $ # Placed in the Public Domain. tid="convert keys" for t in rsa dsa; do # generate user key for agent trace "generating $t key" rm -f $OBJ/$t-key ${SSHKEYGEN} -q -N "" -t $t -f $OBJ/$t-key trace "export $t private to rfc4716 public" ${SSHKEYGEN} -q -e -f $OBJ/$t-key >$OBJ/$t-key-rfc || \ fail "export $t private to rfc4716 public" trace "export $t public to rfc4716 public" ${SSHKEYGEN} -q -e -f $OBJ/$t-key.pub >$OBJ/$t-key-rfc.pub || \ fail "$t public to rfc4716 public" cmp $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub || \ fail "$t rfc4716 exports differ between public and private" trace "import $t rfc4716 public" ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \ fail "$t import rfc4716 public" cut -f1,2 -d " " $OBJ/$t-key.pub >$OBJ/$t-key-nocomment.pub cmp $OBJ/$t-key-nocomment.pub $OBJ/$t-rfc-imported || \ fail "$t imported differs from original" rm -f $OBJ/$t-key $OBJ/$t-key.pub $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub \ $OBJ/$t-rfc-imported $OBJ/$t-key-nocomment.pub done openssh-7.2p2/regress/keygen-knownhosts.sh010064400017500001750000000135251267006270000171630ustar00djmdjm# $OpenBSD: keygen-knownhosts.sh,v 1.3 2015/07/17 03:34:27 djm Exp $ # Placed in the Public Domain. tid="ssh-keygen known_hosts" rm -f $OBJ/kh.* # Generate some keys for testing (just ed25519 for speed) and make a hosts file. for x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do ${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \ fatal "ssh-keygen failed" # Add a comment that we expect should be preserved. echo "# $x" >> $OBJ/kh.hosts ( case "$x" in host-a|host-b) printf "$x " ;; host-c) printf "@cert-authority $x " ;; host-d) printf "@revoked $x " ;; host-e) printf "host-e* " ;; host-f) printf "host-f,host-g,host-h " ;; host-a2) printf "host-a " ;; host-b2) printf "host-b " ;; esac cat $OBJ/kh.${x}.pub # Blank line should be preserved. echo "" >> $OBJ/kh.hosts ) >> $OBJ/kh.hosts done # Generate a variant with an invalid line. We'll use this for most tests, # because keygen should be able to cope and it should be preserved in any # output file. cat $OBJ/kh.hosts >> $OBJ/kh.invalid echo "host-i " >> $OBJ/kh.invalid cp $OBJ/kh.invalid $OBJ/kh.invalid.orig cp $OBJ/kh.hosts $OBJ/kh.hosts.orig expect_key() { _host=$1 _hosts=$2 _key=$3 _line=$4 _mark=$5 _marker="" test "x$_mark" = "xCA" && _marker="@cert-authority " test "x$_mark" = "xREVOKED" && _marker="@revoked " test "x$_line" != "x" && echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect printf "${_marker}$_hosts " >> $OBJ/kh.expect cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect || fatal "${_key}.pub missing" } check_find() { _host=$1 _name=$2 _keygenopt=$3 ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then fail "didn't find $_name" fi } # Find key rm -f $OBJ/kh.expect expect_key host-a host-a host-a 2 expect_key host-a host-a host-a2 20 check_find host-a "simple find" # find CA key rm -f $OBJ/kh.expect expect_key host-c host-c host-c 8 CA check_find host-c "find CA key" # find revoked key rm -f $OBJ/kh.expect expect_key host-d host-d host-d 11 REVOKED check_find host-d "find revoked key" # find key with wildcard rm -f $OBJ/kh.expect expect_key host-e.somedomain "host-e*" host-e 14 check_find host-e.somedomain "find wildcard key" # find key among multiple hosts rm -f $OBJ/kh.expect expect_key host-h "host-f,host-g,host-h " host-f 17 check_find host-h "find multiple hosts" check_hashed_find() { _host=$1 _name=$2 _file=$3 test "x$_file" = "x" && _file=$OBJ/kh.invalid ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \ sed "s/^[^ ]*/$_host/" > $OBJ/kh.result if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then fail "didn't find $_name" fi } # Find key and hash rm -f $OBJ/kh.expect expect_key host-a host-a host-a expect_key host-a host-a host-a2 check_hashed_find host-a "find simple and hash" # Find CA key and hash rm -f $OBJ/kh.expect expect_key host-c host-c host-c "" CA # CA key output is not hashed. check_find host-c "find simple and hash" -H # Find revoked key and hash rm -f $OBJ/kh.expect expect_key host-d host-d host-d "" REVOKED # Revoked key output is not hashed. check_find host-d "find simple and hash" -H # find key with wildcard and hash rm -f $OBJ/kh.expect expect_key host-e "host-e*" host-e "" # Key with wildcard hostname should not be hashed. check_find host-e "find wildcard key" -H # find key among multiple hosts rm -f $OBJ/kh.expect # Comma-separated hostnames should be expanded and hashed. expect_key host-f "host-h " host-f expect_key host-g "host-h " host-f expect_key host-h "host-h " host-f check_hashed_find host-h "find multiple hosts" # Attempt remove key on invalid file. cp $OBJ/kh.invalid.orig $OBJ/kh.invalid ${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded" # Remove key cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple" # Remove CA key cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null # CA key should not be removed. diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA" # Remove revoked key cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null # revoked key should not be removed. diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked" # Remove wildcard cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null grep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" # Remove multiple cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" # Attempt hash on invalid file cp $OBJ/kh.invalid.orig $OBJ/kh.invalid ${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded" diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified" # Hash valid file cp $OBJ/kh.hosts.orig $OBJ/kh.hosts ${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed" diff $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs" grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist" cp $OBJ/kh.hosts $OBJ/kh.hashed.orig # Test lookup rm -f $OBJ/kh.expect expect_key host-a host-a host-a expect_key host-a host-a host-a2 check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts # Test multiple expanded rm -f $OBJ/kh.expect expect_key host-h host-h host-f check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts # Test remove cp $OBJ/kh.hashed.orig $OBJ/kh.hashed ${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null ${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove" openssh-7.2p2/regress/keys-command.sh010064400017500001750000000045751267006270000160620ustar00djmdjm# $OpenBSD: keys-command.sh,v 1.3 2015/05/21 06:40:02 djm Exp $ # Placed in the Public Domain. tid="authorized keys from command" if test -z "$SUDO" ; then echo "skipped (SUDO not set)" echo "need SUDO to create file in /var/run, test won't work without" exit 0 fi rm -f $OBJ/keys-command-args touch $OBJ/keys-command-args chmod a+rw $OBJ/keys-command-args expected_key_text=`awk '{ print $2 }' < $OBJ/rsa.pub` expected_key_fp=`$SSHKEYGEN -lf $OBJ/rsa.pub | awk '{ print $2 }'` # Establish a AuthorizedKeysCommand in /var/run where it will have # acceptable directory permissions. KEY_COMMAND="/var/run/keycommand_${LOGNAME}" cat << _EOF | $SUDO sh -c "rm -f '$KEY_COMMAND' ; cat > '$KEY_COMMAND'" #!/bin/sh echo args: "\$@" >> $OBJ/keys-command-args echo "$PATH" | grep -q mekmitasdigoat && exit 7 test "x\$1" != "x${LOGNAME}" && exit 1 if test $# -eq 6 ; then test "x\$2" != "xblah" && exit 2 test "x\$3" != "x${expected_key_text}" && exit 3 test "x\$4" != "xssh-rsa" && exit 4 test "x\$5" != "x${expected_key_fp}" && exit 5 test "x\$6" != "xblah" && exit 6 fi exec cat "$OBJ/authorized_keys_${LOGNAME}" _EOF $SUDO chmod 0755 "$KEY_COMMAND" if ! $OBJ/check-perm -m keys-command $KEY_COMMAND ; then echo "skipping: $KEY_COMMAND is unsuitable as AuthorizedKeysCommand" $SUDO rm -f $KEY_COMMAND exit 0 fi if [ -x $KEY_COMMAND ]; then cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak verbose "AuthorizedKeysCommand with arguments" ( grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak echo AuthorizedKeysFile none echo AuthorizedKeysCommand $KEY_COMMAND %u blah %k %t %f blah echo AuthorizedKeysCommandUser ${LOGNAME} ) > $OBJ/sshd_proxy # Ensure that $PATH is sanitised in sshd env PATH=$PATH:/sbin/mekmitasdigoat \ ${SSH} -F $OBJ/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "connect failed" fi verbose "AuthorizedKeysCommand without arguments" # Check legacy behavior of no-args resulting in username being passed. ( grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak echo AuthorizedKeysFile none echo AuthorizedKeysCommand $KEY_COMMAND echo AuthorizedKeysCommandUser ${LOGNAME} ) > $OBJ/sshd_proxy # Ensure that $PATH is sanitised in sshd env PATH=$PATH:/sbin/mekmitasdigoat \ ${SSH} -F $OBJ/ssh_proxy somehost true if [ $? -ne 0 ]; then fail "connect failed" fi else echo "SKIPPED: $KEY_COMMAND not executable (/var/run mounted noexec?)" fi $SUDO rm -f $KEY_COMMAND openssh-7.2p2/regress/keyscan.sh010064400017500001750000000007131267006270000151160ustar00djmdjm# $OpenBSD: keyscan.sh,v 1.5 2015/09/11 03:44:21 djm Exp $ # Placed in the Public Domain. tid="keyscan" # remove DSA hostkey rm -f ${OBJ}/host.dsa start_sshd KEYTYPES=`${SSH} -Q key-plain` if ssh_version 1; then KEYTYPES="${KEYTYPES} rsa1" fi for t in $KEYTYPES; do trace "keyscan type $t" ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "ssh-keyscan -t $t failed with: $r" fi done openssh-7.2p2/regress/keytype.sh010064400017500001750000000036441267006270000151610ustar00djmdjm# $OpenBSD: keytype.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ # Placed in the Public Domain. tid="login with different key types" TIME=`which time 2>/dev/null` if test ! -x "$TIME"; then TIME="" fi cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak # Traditional and builtin key types. ktypes="dsa-1024 rsa-2048 rsa-3072 ed25519-512" # Types not present in all OpenSSL versions. for i in `$SSH -Q key`; do case "$i" in ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;; ecdsa-sha2-nistp384) ktypes="$ktypes ecdsa-384" ;; ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;; esac done for kt in $ktypes; do rm -f $OBJ/key.$kt bits=`echo ${kt} | awk -F- '{print $2}'` type=`echo ${kt} | awk -F- '{print $1}'` printf "keygen $type, $bits bits:\t" ${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\ fail "ssh-keygen for type $type, $bits bits failed" done tries="1 2 3" for ut in $ktypes; do htypes=$ut #htypes=$ktypes for ht in $htypes; do case $ht in dsa-1024) t=ssh-dss;; ecdsa-256) t=ecdsa-sha2-nistp256;; ecdsa-384) t=ecdsa-sha2-nistp384;; ecdsa-521) t=ecdsa-sha2-nistp521;; ed25519-512) t=ssh-ed25519;; rsa-*) t=ssh-rsa;; esac trace "ssh connect, userkey $ut, hostkey $ht" ( grep -v HostKey $OBJ/sshd_proxy_bak echo HostKey $OBJ/key.$ht echo PubkeyAcceptedKeyTypes $t echo HostKeyAlgorithms $t ) > $OBJ/sshd_proxy ( grep -v IdentityFile $OBJ/ssh_proxy_bak echo IdentityFile $OBJ/key.$ut echo PubkeyAcceptedKeyTypes $t echo HostKeyAlgorithms $t ) > $OBJ/ssh_proxy ( printf 'localhost-with-alias,127.0.0.1,::1 ' cat $OBJ/key.$ht.pub ) > $OBJ/known_hosts cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER for i in $tries; do printf "userkey $ut, hostkey ${ht}:\t" ${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then fail "ssh userkey $ut, hostkey $ht failed" fi done done done openssh-7.2p2/regress/krl.sh010064400017500001750000000132551267006270000142560ustar00djmdjm# $OpenBSD: krl.sh,v 1.6 2015/01/30 01:11:39 djm Exp $ # Placed in the Public Domain. tid="key revocation lists" # If we don't support ecdsa keys then this tell will be much slower. ECDSA=ecdsa if test "x$TEST_SSH_ECC" != "xyes"; then ECDSA=rsa fi # Do most testing with ssh-keygen; it uses the same verification code as sshd. # Old keys will interfere with ssh-keygen. rm -f $OBJ/revoked-* $OBJ/krl-* # Generate a CA key $SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null || fatal "$SSHKEYGEN CA failed" $SSHKEYGEN -t ed25519 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || fatal "$SSHKEYGEN CA2 failed" # A specification that revokes some certificates by serial numbers # The serial pattern is chosen to ensure the KRL includes list, range and # bitmap sections. cat << EOF >> $OBJ/revoked-serials serial: 1-4 serial: 10 serial: 15 serial: 30 serial: 50 serial: 999 # The following sum to 500-799 serial: 500 serial: 501 serial: 502 serial: 503-600 serial: 700-797 serial: 798 serial: 799 serial: 599-701 # Some multiple consecutive serial number ranges serial: 10000-20000 serial: 30000-40000 EOF # A specification that revokes some certificated by key ID. touch $OBJ/revoked-keyid for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do test "x$n" = "x499" && continue # Fill in by-ID revocation spec. echo "id: revoked $n" >> $OBJ/revoked-keyid done keygen() { N=$1 f=$OBJ/revoked-`printf "%04d" $N` # Vary the keytype. We use mostly ECDSA since this is fastest by far. keytype=$ECDSA case $N in 2 | 10 | 510 | 1001) keytype=rsa;; 4 | 30 | 520 | 1002) keytype=ed25519;; esac $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ || fatal "$SSHKEYGEN failed" # Sign cert $SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \ || fatal "$SSHKEYGEN sign failed" echo $f } # Generate some keys. verbose "$tid: generating test keys" REVOKED_SERIALS="1 4 10 50 500 510 520 799 999" for n in $REVOKED_SERIALS ; do f=`keygen $n` RKEYS="$RKEYS ${f}.pub" RCERTS="$RCERTS ${f}-cert.pub" done UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" UNREVOKED="" for n in $UNREVOKED_SERIALS ; do f=`keygen $n` UKEYS="$UKEYS ${f}.pub" UCERTS="$UCERTS ${f}-cert.pub" done genkrls() { OPTS=$1 $SSHKEYGEN $OPTS -kf $OBJ/krl-empty - /dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ >/dev/null || fatal "$SSHKEYGEN KRL failed" # This should fail as KRLs from serial/key-id spec need the CA specified. $SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" # These should succeed; they specify an explicit CA key. $SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" # These should succeed; they specify an wildcard CA key. $SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ >/dev/null || fatal "$SSHKEYGEN KRL failed" # Revoke the same serials with the second CA key to ensure a multi-CA # KRL is generated. $SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" } ## XXX dump with trace and grep for set cert serials ## XXX test ranges near (u64)-1, etc. verbose "$tid: generating KRLs" genkrls check_krl() { KEY=$1 KRL=$2 EXPECT_REVOKED=$3 TAG=$4 $SSHKEYGEN -Qf $KRL $KEY >/dev/null result=$? if test "x$EXPECT_REVOKED" = "xyes" -a $result -eq 0 ; then fatal "key $KEY not revoked by KRL $KRL: $TAG" elif test "x$EXPECT_REVOKED" = "xno" -a $result -ne 0 ; then fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" fi } test_rev() { FILES=$1 TAG=$2 KEYS_RESULT=$3 ALL_RESULT=$4 SERIAL_RESULT=$5 KEYID_RESULT=$6 CERTS_RESULT=$7 CA_RESULT=$8 SERIAL_WRESULT=$9 KEYID_WRESULT=$10 verbose "$tid: checking revocations for $TAG" for f in $FILES ; do check_krl $f $OBJ/krl-empty no "$TAG" check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" done } test_all() { # wildcard # keys all sr# k.ID cert CA sr.# k.ID test_rev "$RKEYS" "revoked keys" yes yes no no no no no no test_rev "$UKEYS" "unrevoked keys" no no no no no no no no test_rev "$RCERTS" "revoked certs" yes yes yes yes yes yes yes yes test_rev "$UCERTS" "unrevoked certs" no no no no no yes no no } test_all # Check update. Results should be identical. verbose "$tid: testing KRL update" for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do cp -f $OBJ/krl-empty $f genkrls -u done test_all openssh-7.2p2/regress/limit-keytype.sh010064400017500001750000000071501267006270000162710ustar00djmdjm# $OpenBSD: limit-keytype.sh,v 1.4 2015/10/29 08:05:17 djm Exp $ # Placed in the Public Domain. tid="restrict pubkey type" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig # Create a CA key ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ fatal "ssh-keygen failed" # Make some keys and a certificate. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t dsa -f $OBJ/user_key4 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || fatal "couldn't sign user_key1" # Copy the private key alongside the cert to allow better control of when # it is offered. mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub" echo mekmitasdigoat > $OBJ/authorized_principals_$USER cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER prepare_config() { ( grep -v "Protocol" $OBJ/sshd_proxy.orig echo "Protocol 2" echo "AuthenticationMethods publickey" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" for x in "$@" ; do echo "$x" done ) > $OBJ/sshd_proxy } prepare_config # Check we can log in with all key types. ${SSH} $certopts proxy true || fatal "cert failed" ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" # Allow plain Ed25519 and RSA. The certificate should fail. verbose "allow rsa,ed25519" prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519" ${SSH} $certopts proxy true && fatal "cert succeeded" ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" # Allow Ed25519 only. verbose "allow ed25519" prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519" ${SSH} $certopts proxy true && fatal "cert succeeded" ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" # Allow all certs. Plain keys should fail. verbose "allow cert only" prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com" ${SSH} $certopts proxy true || fatal "cert failed" ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" # Allow RSA in main config, Ed25519 for non-existent user. verbose "match w/ no match" prepare_config "PubkeyAcceptedKeyTypes ssh-rsa" \ "Match user x$USER" "PubkeyAcceptedKeyTypes +ssh-ed25519" ${SSH} $certopts proxy true && fatal "cert succeeded" ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" # Allow only DSA in main config, Ed25519 for user. verbose "match w/ matching" prepare_config "PubkeyAcceptedKeyTypes ssh-dss" \ "Match user $USER" "PubkeyAcceptedKeyTypes +ssh-ed25519" ${SSH} $certopts proxy true || fatal "cert failed" ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" ${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded" openssh-7.2p2/regress/localcommand.sh010064400017500001750000000006161267006270000161140ustar00djmdjm# $OpenBSD: localcommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="localcommand" echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy for p in ${SSH_PROTOCOLS}; do verbose "test $tid: proto $p localcommand" a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` if [ "$a" != "foo" ] ; then fail "$tid proto $p" fi done openssh-7.2p2/regress/login-timeout.sh010064400017500001750000000017051267006270000162570ustar00djmdjm# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $ # Placed in the Public Domain. tid="connect after login grace timeout" trace "test login grace with privsep" cp $OBJ/sshd_config $OBJ/sshd_config.orig grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config echo "LoginGraceTime 10s" >> $OBJ/sshd_config echo "MaxStartups 1" >> $OBJ/sshd_config start_sshd (echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & sleep 15 ${SSH} -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect after login grace timeout failed with privsep" fi $SUDO kill `$SUDO cat $PIDFILE` trace "test login grace without privsep" echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config start_sshd sleep 1 (echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & sleep 15 ${SSH} -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect after login grace timeout failed without privsep" fi openssh-7.2p2/regress/modpipe.c010075500017500001750000000104501267006270000147300ustar00djmdjm/* * Copyright (c) 2012 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ #include "includes.h" #include #include #include #include #include #include #include #include "openbsd-compat/getopt_long.c" static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); static void err(int r, const char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "%s: ", strerror(errno)); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); exit(r); } static void errx(int r, const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); exit(r); } static void usage(void) { fprintf(stderr, "Usage: modpipe -w [-m modspec ...] < in > out\n"); fprintf(stderr, "modspec is one of:\n"); fprintf(stderr, " xor:offset:value - XOR \"value\" at \"offset\"\n"); fprintf(stderr, " andor:offset:val1:val2 - AND \"val1\" then OR \"val2\" at \"offset\"\n"); exit(1); } #define MAX_MODIFICATIONS 256 struct modification { enum { MOD_XOR, MOD_AND_OR } what; unsigned long long offset; u_int8_t m1, m2; }; static void parse_modification(const char *s, struct modification *m) { char what[16+1]; int n, m1, m2; bzero(m, sizeof(*m)); if ((n = sscanf(s, "%16[^:]%*[:]%llu%*[:]%i%*[:]%i", what, &m->offset, &m1, &m2)) < 3) errx(1, "Invalid modification spec \"%s\"", s); if (strcasecmp(what, "xor") == 0) { if (n > 3) errx(1, "Invalid modification spec \"%s\"", s); if (m1 < 0 || m1 > 0xff) errx(1, "Invalid XOR modification value"); m->what = MOD_XOR; m->m1 = m1; } else if (strcasecmp(what, "andor") == 0) { if (n != 4) errx(1, "Invalid modification spec \"%s\"", s); if (m1 < 0 || m1 > 0xff) errx(1, "Invalid AND modification value"); if (m2 < 0 || m2 > 0xff) errx(1, "Invalid OR modification value"); m->what = MOD_AND_OR; m->m1 = m1; m->m2 = m2; } else errx(1, "Invalid modification type \"%s\"", what); } int main(int argc, char **argv) { int ch; u_char buf[8192]; size_t total; ssize_t r, s, o; struct modification mods[MAX_MODIFICATIONS]; u_int i, wflag = 0, num_mods = 0; while ((ch = getopt(argc, argv, "wm:")) != -1) { switch (ch) { case 'm': if (num_mods >= MAX_MODIFICATIONS) errx(1, "Too many modifications"); parse_modification(optarg, &(mods[num_mods++])); break; case 'w': wflag = 1; break; default: usage(); /* NOTREACHED */ } } for (total = 0;;) { r = s = read(STDIN_FILENO, buf, sizeof(buf)); if (r == 0) break; if (r < 0) { if (errno == EAGAIN || errno == EINTR) continue; err(1, "read"); } for (i = 0; i < num_mods; i++) { if (mods[i].offset < total || mods[i].offset >= total + s) continue; switch (mods[i].what) { case MOD_XOR: buf[mods[i].offset - total] ^= mods[i].m1; break; case MOD_AND_OR: buf[mods[i].offset - total] &= mods[i].m1; buf[mods[i].offset - total] |= mods[i].m2; break; } } for (o = 0; o < s; o += r) { r = write(STDOUT_FILENO, buf, s - o); if (r == 0) break; if (r < 0) { if (errno == EAGAIN || errno == EINTR) continue; err(1, "write"); } } total += s; } /* Warn if modifications not reached in input stream */ r = 0; for (i = 0; wflag && i < num_mods; i++) { if (mods[i].offset < total) continue; r = 1; fprintf(stderr, "modpipe: warning - mod %u not reached\n", i); } return r; } openssh-7.2p2/regress/multiplex.sh010064400017500001750000000161651267006270000155140ustar00djmdjm# $OpenBSD: multiplex.sh,v 1.27 2014/12/22 06:14:29 djm Exp $ # Placed in the Public Domain. CTL=/tmp/openssh.regress.ctl-sock.$$ tid="connection multiplexing" NC=$OBJ/netcat trace "will use ProxyCommand $proxycmd" if config_defined DISABLE_FD_PASSING ; then echo "skipped (not supported on this platform)" exit 0 fi P=3301 # test port wait_for_mux_master_ready() { for i in 1 2 3 4 5; do ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \ >/dev/null 2>&1 && return 0 sleep $i done fatal "mux master never becomes ready" } start_sshd start_mux_master() { trace "start master, fork to background" ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \ -E $TEST_REGRESS_LOGFILE 2>&1 & # NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors. SSH_PID=$! wait_for_mux_master_ready } start_mux_master verbose "test $tid: envpass" trace "env passing over multiplexed connection" _XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' test X"$_XXX_TEST" = X"blah" EOF if [ $? -ne 0 ]; then fail "environment not found" fi verbose "test $tid: transfer" rm -f ${COPY} trace "ssh transfer over multiplexed connection and check result" ${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" rm -f ${COPY} trace "ssh transfer over multiplexed connection and check result" ${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" rm -f ${COPY} trace "sftp transfer over multiplexed connection and check result" echo "get ${DATA} ${COPY}" | \ ${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1 test -f ${COPY} || fail "sftp: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}" rm -f ${COPY} trace "scp transfer over multiplexed connection and check result" ${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1 test -f ${COPY} || fail "scp: failed copy ${DATA}" cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" rm -f ${COPY} verbose "test $tid: forward" trace "forward over TCP/IP and check result" $NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} > /dev/null & netcat_pid=$! ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 $NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY} cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" kill $netcat_pid 2>/dev/null rm -f ${COPY} $OBJ/unix-[123].fwd trace "forward over UNIX and check result" $NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null & netcat_pid=$! ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 $NC -U $OBJ/unix-3.fwd < /dev/null > ${COPY} 2>/dev/null cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" kill $netcat_pid 2>/dev/null rm -f ${COPY} $OBJ/unix-[123].fwd for s in 0 1 4 5 44; do trace "exit status $s over multiplexed connection" verbose "test $tid: status $s" ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s r=$? if [ $r -ne $s ]; then fail "exit code mismatch for protocol $p: $r != $s" fi # same with early close of stdout/err trace "exit status $s with early close over multiplexed connection" ${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \ exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' r=$? if [ $r -ne $s ]; then fail "exit code (with sleep) mismatch for protocol $p: $r != $s" fi done verbose "test $tid: cmd check" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ || fail "check command failed" verbose "test $tid: cmd forward local (TCP)" ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \ || fail "request local forward failed" ${SSH} -F $OBJ/ssh_config -p$P otherhost true \ || fail "connect to local forward port failed" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \ || fail "cancel local forward failed" ${SSH} -F $OBJ/ssh_config -p$P otherhost true \ && fail "local forward port still listening" verbose "test $tid: cmd forward remote (TCP)" ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \ || fail "request remote forward failed" ${SSH} -F $OBJ/ssh_config -p$P otherhost true \ || fail "connect to remote forwarded port failed" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \ || fail "cancel remote forward failed" ${SSH} -F $OBJ/ssh_config -p$P otherhost true \ && fail "remote forward port still listening" verbose "test $tid: cmd forward local (UNIX)" ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ || fail "request local forward failed" echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ || fail "connect to local forward path failed" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ || fail "cancel local forward failed" N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) test ${N} -eq 0 || fail "local forward path still listening" rm -f $OBJ/unix-1.fwd verbose "test $tid: cmd forward remote (UNIX)" ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ || fail "request remote forward failed" echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ || fail "connect to remote forwarded path failed" ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ || fail "cancel remote forward failed" N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) test ${N} -eq 0 || fail "remote forward path still listening" rm -f $OBJ/unix-1.fwd verbose "test $tid: cmd exit" ${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ || fail "send exit command failed" # Wait for master to exit wait $SSH_PID kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed" # Restart master and test -O stop command with master using -N verbose "test $tid: cmd stop" trace "restart master, fork to background" start_mux_master # start a long-running command then immediately request a stop ${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \ >>$TEST_REGRESS_LOGFILE 2>&1 & SLEEP_PID=$! ${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ || fail "send stop command failed" # wait until both long-running command and master have exited. wait $SLEEP_PID [ $! != 0 ] || fail "waiting for concurrent command" wait $SSH_PID [ $! != 0 ] || fail "waiting for master stop" kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed" SSH_PID="" # Already gone, so don't kill in cleanup openssh-7.2p2/regress/multipubkey.sh010064400017500001750000000044771267006270000160460ustar00djmdjm# $OpenBSD: multipubkey.sh,v 1.1 2014/12/22 08:06:03 djm Exp $ # Placed in the Public Domain. tid="multiple pubkey" rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig # Create a CA key ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ fatal "ssh-keygen failed" # Make some keys and a certificate. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key1 || fail "couldn't sign user_key1" # Copy the private key alongside the cert to allow better control of when # it is offered. mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1.pub cp -p $OBJ/user_key1 $OBJ/cert_user_key1 grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" opts="$opts -i $OBJ/cert_user_key1 -i $OBJ/user_key1 -i $OBJ/user_key2" for privsep in no yes; do ( grep -v "Protocol" $OBJ/sshd_proxy.orig echo "Protocol 2" echo "UsePrivilegeSeparation $privsep" echo "AuthenticationMethods publickey,publickey" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" ) > $OBJ/sshd_proxy # Single key should fail. rm -f $OBJ/authorized_principals_$USER cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER ${SSH} $opts proxy true && fail "ssh succeeded with key" # Single key with same-public cert should fail. echo mekmitasdigoat > $OBJ/authorized_principals_$USER cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER ${SSH} $opts proxy true && fail "ssh succeeded with key+cert" # Multiple plain keys should succeed. rm -f $OBJ/authorized_principals_$USER cat $OBJ/user_key1.pub $OBJ/user_key2.pub > \ $OBJ/authorized_keys_$USER ${SSH} $opts proxy true || fail "ssh failed with multiple keys" # Cert and different key should succeed # Key and different-public cert should succeed. echo mekmitasdigoat > $OBJ/authorized_principals_$USER cat $OBJ/user_key2.pub > $OBJ/authorized_keys_$USER ${SSH} $opts proxy true || fail "ssh failed with key/cert" done openssh-7.2p2/regress/netcat.c010064400017500001750000001210111267006270000145420ustar00djmdjm/* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */ /* * Copyright (c) 2001 Eric Jackson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Re-written nc(1) for OpenBSD. Original implementation by * *Hobbit* . */ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "atomicio.h" #ifdef HAVE_POLL_H #include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif /* Telnet options from arpa/telnet.h */ #define IAC 255 #define DONT 254 #define DO 253 #define WONT 252 #define WILL 251 #ifndef SUN_LEN #define SUN_LEN(su) \ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) #endif #define PORT_MAX 65535 #define PORT_MAX_LEN 6 #define UNIX_DG_TMP_SOCKET_SIZE 19 #define POLL_STDIN 0 #define POLL_NETOUT 1 #define POLL_NETIN 2 #define POLL_STDOUT 3 #define BUFSIZE 16384 /* Command Line Options */ int dflag; /* detached, no stdin */ int Fflag; /* fdpass sock to stdout */ unsigned int iflag; /* Interval Flag */ int kflag; /* More than one connect */ int lflag; /* Bind to local port */ int Nflag; /* shutdown() network socket */ int nflag; /* Don't do name look up */ char *Pflag; /* Proxy username */ char *pflag; /* Localport flag */ int rflag; /* Random ports flag */ char *sflag; /* Source Address */ int tflag; /* Telnet Emulation */ int uflag; /* UDP - Default to TCP */ int vflag; /* Verbosity */ int xflag; /* Socks proxy */ int zflag; /* Port Scan Flag */ int Dflag; /* sodebug */ int Iflag; /* TCP receive buffer size */ int Oflag; /* TCP send buffer size */ int Sflag; /* TCP MD5 signature option */ int Tflag = -1; /* IP Type of Service */ int rtableid = -1; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; char *unix_dg_tmp_socket; void atelnet(int, unsigned char *, unsigned int); void build_ports(char *); void help(void); int local_listen(char *, char *, struct addrinfo); void readwrite(int); void fdpass(int nfd) __attribute__((noreturn)); int remote_connect(const char *, const char *, struct addrinfo); int timeout_connect(int, const struct sockaddr *, socklen_t); int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); int udptest(int); int unix_bind(char *); int unix_connect(char *); int unix_listen(char *); void set_common_sockopts(int); int map_tos(char *, int *); void report_connect(const struct sockaddr *, socklen_t); void usage(int); ssize_t drainbuf(int, unsigned char *, size_t *); ssize_t fillbuf(int, unsigned char *, size_t *); static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); static void warn(const char *, ...) __attribute__((format(printf, 1, 2))); static void err(int r, const char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "%s: ", strerror(errno)); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); exit(r); } static void errx(int r, const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); exit(r); } static void warn(const char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "%s: ", strerror(errno)); vfprintf(stderr, fmt, args); fputc('\n', stderr); va_end(args); } int main(int argc, char *argv[]) { int ch, s, ret, socksv; char *host, *uport; struct addrinfo hints; struct servent *sv; socklen_t len; struct sockaddr_storage cliaddr; char *proxy = NULL; const char *errstr, *proxyhost = "", *proxyport = NULL; struct addrinfo proxyhints; char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; ret = 1; s = 0; socksv = 5; host = NULL; uport = NULL; sv = NULL; while ((ch = getopt(argc, argv, "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { switch (ch) { case '4': family = AF_INET; break; case '6': family = AF_INET6; break; case 'U': family = AF_UNIX; break; case 'X': if (strcasecmp(optarg, "connect") == 0) socksv = -1; /* HTTP proxy CONNECT */ else if (strcmp(optarg, "4") == 0) socksv = 4; /* SOCKS v.4 */ else if (strcmp(optarg, "5") == 0) socksv = 5; /* SOCKS v.5 */ else errx(1, "unsupported proxy protocol"); break; case 'd': dflag = 1; break; case 'F': Fflag = 1; break; case 'h': help(); break; case 'i': iflag = strtonum(optarg, 0, UINT_MAX, &errstr); if (errstr) errx(1, "interval %s: %s", errstr, optarg); break; case 'k': kflag = 1; break; case 'l': lflag = 1; break; case 'N': Nflag = 1; break; case 'n': nflag = 1; break; case 'P': Pflag = optarg; break; case 'p': pflag = optarg; break; case 'r': rflag = 1; break; case 's': sflag = optarg; break; case 't': tflag = 1; break; case 'u': uflag = 1; break; #ifdef SO_RTABLE case 'V': rtableid = (int)strtonum(optarg, 0, RT_TABLEID_MAX, &errstr); if (errstr) errx(1, "rtable %s: %s", errstr, optarg); break; #endif case 'v': vflag = 1; break; case 'w': timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); if (errstr) errx(1, "timeout %s: %s", errstr, optarg); timeout *= 1000; break; case 'x': xflag = 1; if ((proxy = strdup(optarg)) == NULL) errx(1, "strdup"); break; case 'z': zflag = 1; break; case 'D': Dflag = 1; break; case 'I': Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); if (errstr != NULL) errx(1, "TCP receive window %s: %s", errstr, optarg); break; case 'O': Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); if (errstr != NULL) errx(1, "TCP send window %s: %s", errstr, optarg); break; case 'S': Sflag = 1; break; case 'T': errstr = NULL; errno = 0; if (map_tos(optarg, &Tflag)) break; if (strlen(optarg) > 1 && optarg[0] == '0' && optarg[1] == 'x') Tflag = (int)strtol(optarg, NULL, 16); else Tflag = (int)strtonum(optarg, 0, 255, &errstr); if (Tflag < 0 || Tflag > 255 || errstr || errno) errx(1, "illegal tos value %s", optarg); break; default: usage(1); } } argc -= optind; argv += optind; /* Cruft to make sure options are clean, and used properly. */ if (argv[0] && !argv[1] && family == AF_UNIX) { host = argv[0]; uport = NULL; } else if (argv[0] && !argv[1]) { if (!lflag) usage(1); uport = argv[0]; host = NULL; } else if (argv[0] && argv[1]) { host = argv[0]; uport = argv[1]; } else usage(1); if (lflag && sflag) errx(1, "cannot use -s and -l"); if (lflag && pflag) errx(1, "cannot use -p and -l"); if (lflag && zflag) errx(1, "cannot use -z and -l"); if (!lflag && kflag) errx(1, "must use -l with -k"); /* Get name of temporary socket for unix datagram client */ if ((family == AF_UNIX) && uflag && !lflag) { if (sflag) { unix_dg_tmp_socket = sflag; } else { strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", UNIX_DG_TMP_SOCKET_SIZE); if (mktemp(unix_dg_tmp_socket_buf) == NULL) err(1, "mktemp"); unix_dg_tmp_socket = unix_dg_tmp_socket_buf; } } /* Initialize addrinfo structure. */ if (family != AF_UNIX) { memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; if (nflag) hints.ai_flags |= AI_NUMERICHOST; } if (xflag) { if (uflag) errx(1, "no proxy support for UDP mode"); if (lflag) errx(1, "no proxy support for listen"); if (family == AF_UNIX) errx(1, "no proxy support for unix sockets"); /* XXX IPv6 transport to proxy would probably work */ if (family == AF_INET6) errx(1, "no proxy support for IPv6"); if (sflag) errx(1, "no proxy support for local source address"); proxyhost = strsep(&proxy, ":"); proxyport = proxy; memset(&proxyhints, 0, sizeof(struct addrinfo)); proxyhints.ai_family = family; proxyhints.ai_socktype = SOCK_STREAM; proxyhints.ai_protocol = IPPROTO_TCP; if (nflag) proxyhints.ai_flags |= AI_NUMERICHOST; } if (lflag) { int connfd; ret = 0; if (family == AF_UNIX) { if (uflag) s = unix_bind(host); else s = unix_listen(host); } /* Allow only one connection at a time, but stay alive. */ for (;;) { if (family != AF_UNIX) s = local_listen(host, uport, hints); if (s < 0) err(1, "local_listen"); /* * For UDP and -k, don't connect the socket, let it * receive datagrams from multiple socket pairs. */ if (uflag && kflag) readwrite(s); /* * For UDP and not -k, we will use recvfrom() initially * to wait for a caller, then use the regular functions * to talk to the caller. */ else if (uflag && !kflag) { int rv, plen; char buf[16384]; struct sockaddr_storage z; len = sizeof(z); plen = 2048; rv = recvfrom(s, buf, plen, MSG_PEEK, (struct sockaddr *)&z, &len); if (rv < 0) err(1, "recvfrom"); rv = connect(s, (struct sockaddr *)&z, len); if (rv < 0) err(1, "connect"); if (vflag) report_connect((struct sockaddr *)&z, len); readwrite(s); } else { len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)&cliaddr, &len); if (connfd == -1) { /* For now, all errnos are fatal */ err(1, "accept"); } if (vflag) report_connect((struct sockaddr *)&cliaddr, len); readwrite(connfd); close(connfd); } if (family != AF_UNIX) close(s); else if (uflag) { if (connect(s, NULL, 0) < 0) err(1, "connect"); } if (!kflag) break; } } else if (family == AF_UNIX) { ret = 0; if ((s = unix_connect(host)) > 0 && !zflag) { readwrite(s); close(s); } else ret = 1; if (uflag) unlink(unix_dg_tmp_socket); exit(ret); } else { int i = 0; /* Construct the portlist[] array. */ build_ports(uport); /* Cycle through portlist, connecting to each port. */ for (i = 0; portlist[i] != NULL; i++) { if (s) close(s); if (xflag) s = socks_connect(host, portlist[i], hints, proxyhost, proxyport, proxyhints, socksv, Pflag); else s = remote_connect(host, portlist[i], hints); if (s < 0) continue; ret = 0; if (vflag || zflag) { /* For UDP, make sure we are connected. */ if (uflag) { if (udptest(s) == -1) { ret = 1; continue; } } /* Don't look up port if -n. */ if (nflag) sv = NULL; else { sv = getservbyport( ntohs(atoi(portlist[i])), uflag ? "udp" : "tcp"); } fprintf(stderr, "Connection to %s %s port [%s/%s] " "succeeded!\n", host, portlist[i], uflag ? "udp" : "tcp", sv ? sv->s_name : "*"); } if (Fflag) fdpass(s); else if (!zflag) readwrite(s); } } if (s) close(s); exit(ret); } /* * unix_bind() * Returns a unix socket bound to the given path */ int unix_bind(char *path) { struct sockaddr_un sun_sa; int s; /* Create unix domain socket. */ if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) return (-1); memset(&sun_sa, 0, sizeof(struct sockaddr_un)); sun_sa.sun_family = AF_UNIX; if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= sizeof(sun_sa.sun_path)) { close(s); errno = ENAMETOOLONG; return (-1); } if (bind(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { close(s); return (-1); } return (s); } /* * unix_connect() * Returns a socket connected to a local unix socket. Returns -1 on failure. */ int unix_connect(char *path) { struct sockaddr_un sun_sa; int s; if (uflag) { if ((s = unix_bind(unix_dg_tmp_socket)) < 0) return (-1); } else { if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) return (-1); } (void)fcntl(s, F_SETFD, FD_CLOEXEC); memset(&sun_sa, 0, sizeof(struct sockaddr_un)); sun_sa.sun_family = AF_UNIX; if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= sizeof(sun_sa.sun_path)) { close(s); errno = ENAMETOOLONG; return (-1); } if (connect(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { close(s); return (-1); } return (s); } /* * unix_listen() * Create a unix domain socket, and listen on it. */ int unix_listen(char *path) { int s; if ((s = unix_bind(path)) < 0) return (-1); if (listen(s, 5) < 0) { close(s); return (-1); } return (s); } /* * remote_connect() * Returns a socket connected to a remote host. Properly binds to a local * port or source address if needed. Returns -1 on failure. */ int remote_connect(const char *host, const char *port, struct addrinfo hints) { struct addrinfo *res, *res0; int s, error; #if defined(SO_RTABLE) || defined(SO_BINDANY) int on = 1; #endif if ((error = getaddrinfo(host, port, &hints, &res))) errx(1, "getaddrinfo: %s", gai_strerror(error)); res0 = res; do { if ((s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol)) < 0) continue; #ifdef SO_RTABLE if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, sizeof(rtableid)) == -1)) err(1, "setsockopt SO_RTABLE"); #endif /* Bind to a local port or source address if specified. */ if (sflag || pflag) { struct addrinfo ahints, *ares; #ifdef SO_BINDANY /* try SO_BINDANY, but don't insist */ setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); #endif memset(&ahints, 0, sizeof(struct addrinfo)); ahints.ai_family = res0->ai_family; ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; ahints.ai_flags = AI_PASSIVE; if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) errx(1, "getaddrinfo: %s", gai_strerror(error)); if (bind(s, (struct sockaddr *)ares->ai_addr, ares->ai_addrlen) < 0) err(1, "bind failed"); freeaddrinfo(ares); } set_common_sockopts(s); if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; else if (vflag) warn("connect to %s port %s (%s) failed", host, port, uflag ? "udp" : "tcp"); close(s); s = -1; } while ((res0 = res0->ai_next) != NULL); freeaddrinfo(res); return (s); } int timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) { struct pollfd pfd; socklen_t optlen; int flags = 0, optval; int ret; if (timeout != -1) { flags = fcntl(s, F_GETFL, 0); if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) err(1, "set non-blocking mode"); } if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { pfd.fd = s; pfd.events = POLLOUT; if ((ret = poll(&pfd, 1, timeout)) == 1) { optlen = sizeof(optval); if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, &optlen)) == 0) { errno = optval; ret = optval == 0 ? 0 : -1; } } else if (ret == 0) { errno = ETIMEDOUT; ret = -1; } else err(1, "poll failed"); } if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) err(1, "restoring flags"); return (ret); } /* * local_listen() * Returns a socket listening on a local port, binds to specified source * address. Returns -1 on failure. */ int local_listen(char *host, char *port, struct addrinfo hints) { struct addrinfo *res, *res0; int s, ret, x = 1; int error; /* Allow nodename to be null. */ hints.ai_flags |= AI_PASSIVE; /* * In the case of binding to a wildcard address * default to binding to an ipv4 address. */ if (host == NULL && hints.ai_family == AF_UNSPEC) hints.ai_family = AF_INET; if ((error = getaddrinfo(host, port, &hints, &res))) errx(1, "getaddrinfo: %s", gai_strerror(error)); res0 = res; do { if ((s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol)) < 0) continue; #ifdef SO_RTABLE if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, sizeof(rtableid)) == -1)) err(1, "setsockopt SO_RTABLE"); #endif #ifdef SO_REUSEPORT ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); if (ret == -1) err(1, "setsockopt"); #endif set_common_sockopts(s); if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) break; close(s); s = -1; } while ((res0 = res0->ai_next) != NULL); if (!uflag && s != -1) { if (listen(s, 1) < 0) err(1, "listen"); } freeaddrinfo(res); return (s); } /* * readwrite() * Loop that polls on the network file descriptor and stdin. */ void readwrite(int net_fd) { struct pollfd pfd[4]; int stdin_fd = STDIN_FILENO; int stdout_fd = STDOUT_FILENO; unsigned char netinbuf[BUFSIZE]; size_t netinbufpos = 0; unsigned char stdinbuf[BUFSIZE]; size_t stdinbufpos = 0; int n, num_fds; ssize_t ret; /* don't read from stdin if requested */ if (dflag) stdin_fd = -1; /* stdin */ pfd[POLL_STDIN].fd = stdin_fd; pfd[POLL_STDIN].events = POLLIN; /* network out */ pfd[POLL_NETOUT].fd = net_fd; pfd[POLL_NETOUT].events = 0; /* network in */ pfd[POLL_NETIN].fd = net_fd; pfd[POLL_NETIN].events = POLLIN; /* stdout */ pfd[POLL_STDOUT].fd = stdout_fd; pfd[POLL_STDOUT].events = 0; while (1) { /* both inputs are gone, buffers are empty, we are done */ if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 && stdinbufpos == 0 && netinbufpos == 0) { close(net_fd); return; } /* both outputs are gone, we can't continue */ if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { close(net_fd); return; } /* listen and net in gone, queues empty, done */ if (lflag && pfd[POLL_NETIN].fd == -1 && stdinbufpos == 0 && netinbufpos == 0) { close(net_fd); return; } /* help says -i is for "wait between lines sent". We read and * write arbitrary amounts of data, and we don't want to start * scanning for newlines, so this is as good as it gets */ if (iflag) sleep(iflag); /* poll */ num_fds = poll(pfd, 4, timeout); /* treat poll errors */ if (num_fds == -1) { close(net_fd); err(1, "polling error"); } /* timeout happened */ if (num_fds == 0) return; /* treat socket error conditions */ for (n = 0; n < 4; n++) { if (pfd[n].revents & (POLLERR|POLLNVAL)) { pfd[n].fd = -1; } } /* reading is possible after HUP */ if (pfd[POLL_STDIN].events & POLLIN && pfd[POLL_STDIN].revents & POLLHUP && ! (pfd[POLL_STDIN].revents & POLLIN)) pfd[POLL_STDIN].fd = -1; if (pfd[POLL_NETIN].events & POLLIN && pfd[POLL_NETIN].revents & POLLHUP && ! (pfd[POLL_NETIN].revents & POLLIN)) pfd[POLL_NETIN].fd = -1; if (pfd[POLL_NETOUT].revents & POLLHUP) { if (Nflag) shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); pfd[POLL_NETOUT].fd = -1; } /* if HUP, stop watching stdout */ if (pfd[POLL_STDOUT].revents & POLLHUP) pfd[POLL_STDOUT].fd = -1; /* if no net out, stop watching stdin */ if (pfd[POLL_NETOUT].fd == -1) pfd[POLL_STDIN].fd = -1; /* if no stdout, stop watching net in */ if (pfd[POLL_STDOUT].fd == -1) { if (pfd[POLL_NETIN].fd != -1) shutdown(pfd[POLL_NETIN].fd, SHUT_RD); pfd[POLL_NETIN].fd = -1; } /* try to read from stdin */ if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, &stdinbufpos); /* error or eof on stdin - remove from pfd */ if (ret == 0 || ret == -1) pfd[POLL_STDIN].fd = -1; /* read something - poll net out */ if (stdinbufpos > 0) pfd[POLL_NETOUT].events = POLLOUT; /* filled buffer - remove self from polling */ if (stdinbufpos == BUFSIZE) pfd[POLL_STDIN].events = 0; } /* try to write to network */ if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, &stdinbufpos); if (ret == -1) pfd[POLL_NETOUT].fd = -1; /* buffer empty - remove self from polling */ if (stdinbufpos == 0) pfd[POLL_NETOUT].events = 0; /* buffer no longer full - poll stdin again */ if (stdinbufpos < BUFSIZE) pfd[POLL_STDIN].events = POLLIN; } /* try to read from network */ if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, &netinbufpos); if (ret == -1) pfd[POLL_NETIN].fd = -1; /* eof on net in - remove from pfd */ if (ret == 0) { shutdown(pfd[POLL_NETIN].fd, SHUT_RD); pfd[POLL_NETIN].fd = -1; } /* read something - poll stdout */ if (netinbufpos > 0) pfd[POLL_STDOUT].events = POLLOUT; /* filled buffer - remove self from polling */ if (netinbufpos == BUFSIZE) pfd[POLL_NETIN].events = 0; /* handle telnet */ if (tflag) atelnet(pfd[POLL_NETIN].fd, netinbuf, netinbufpos); } /* try to write to stdout */ if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, &netinbufpos); if (ret == -1) pfd[POLL_STDOUT].fd = -1; /* buffer empty - remove self from polling */ if (netinbufpos == 0) pfd[POLL_STDOUT].events = 0; /* buffer no longer full - poll net in again */ if (netinbufpos < BUFSIZE) pfd[POLL_NETIN].events = POLLIN; } /* stdin gone and queue empty? */ if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { if (pfd[POLL_NETOUT].fd != -1 && Nflag) shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); pfd[POLL_NETOUT].fd = -1; } /* net in gone and queue empty? */ if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { pfd[POLL_STDOUT].fd = -1; } } } ssize_t drainbuf(int fd, unsigned char *buf, size_t *bufpos) { ssize_t n; ssize_t adjust; n = write(fd, buf, *bufpos); /* don't treat EAGAIN, EINTR as error */ if (n == -1 && (errno == EAGAIN || errno == EINTR)) n = -2; if (n <= 0) return n; /* adjust buffer */ adjust = *bufpos - n; if (adjust > 0) memmove(buf, buf + n, adjust); *bufpos -= n; return n; } ssize_t fillbuf(int fd, unsigned char *buf, size_t *bufpos) { size_t num = BUFSIZE - *bufpos; ssize_t n; n = read(fd, buf + *bufpos, num); /* don't treat EAGAIN, EINTR as error */ if (n == -1 && (errno == EAGAIN || errno == EINTR)) n = -2; if (n <= 0) return n; *bufpos += n; return n; } /* * fdpass() * Pass the connected file descriptor to stdout and exit. */ void fdpass(int nfd) { #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct cmsghdr *cmsg; #endif struct iovec vec; char ch = '\0'; struct pollfd pfd; ssize_t r; memset(&msg, 0, sizeof(msg)); #ifdef HAVE_ACCRIGHTS_IN_MSGHDR msg.msg_accrights = (caddr_t)&nfd; msg.msg_accrightslen = sizeof(nfd); #else memset(&cmsgbuf, 0, sizeof(cmsgbuf)); msg.msg_control = (caddr_t)&cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(cmsg) = nfd; #endif vec.iov_base = &ch; vec.iov_len = 1; msg.msg_iov = &vec; msg.msg_iovlen = 1; bzero(&pfd, sizeof(pfd)); pfd.fd = STDOUT_FILENO; for (;;) { r = sendmsg(STDOUT_FILENO, &msg, 0); if (r == -1) { if (errno == EAGAIN || errno == EINTR) { pfd.events = POLLOUT; if (poll(&pfd, 1, -1) == -1) err(1, "poll"); continue; } err(1, "sendmsg"); } else if (r == -1) errx(1, "sendmsg: unexpected return value %zd", r); else break; } exit(0); #else errx(1, "%s: file descriptor passing not supported", __func__); #endif } /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ void atelnet(int nfd, unsigned char *buf, unsigned int size) { unsigned char *p, *end; unsigned char obuf[4]; if (size < 3) return; end = buf + size - 2; for (p = buf; p < end; p++) { if (*p != IAC) continue; obuf[0] = IAC; p++; if ((*p == WILL) || (*p == WONT)) obuf[1] = DONT; else if ((*p == DO) || (*p == DONT)) obuf[1] = WONT; else continue; p++; obuf[2] = *p; if (atomicio(vwrite, nfd, obuf, 3) != 3) warn("Write Error!"); } } /* * build_ports() * Build an array of ports in portlist[], listing each port * that we should try to connect to. */ void build_ports(char *p) { const char *errstr; char *n; int hi, lo, cp; int x = 0; if ((n = strchr(p, '-')) != NULL) { *n = '\0'; n++; /* Make sure the ports are in order: lowest->highest. */ hi = strtonum(n, 1, PORT_MAX, &errstr); if (errstr) errx(1, "port number %s: %s", errstr, n); lo = strtonum(p, 1, PORT_MAX, &errstr); if (errstr) errx(1, "port number %s: %s", errstr, p); if (lo > hi) { cp = hi; hi = lo; lo = cp; } /* Load ports sequentially. */ for (cp = lo; cp <= hi; cp++) { portlist[x] = calloc(1, PORT_MAX_LEN); if (portlist[x] == NULL) errx(1, "calloc"); snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); x++; } /* Randomly swap ports. */ if (rflag) { int y; char *c; for (x = 0; x <= (hi - lo); x++) { y = (arc4random() & 0xFFFF) % (hi - lo); c = portlist[x]; portlist[x] = portlist[y]; portlist[y] = c; } } } else { hi = strtonum(p, 1, PORT_MAX, &errstr); if (errstr) errx(1, "port number %s: %s", errstr, p); portlist[0] = strdup(p); if (portlist[0] == NULL) errx(1, "strdup"); } } /* * udptest() * Do a few writes to see if the UDP port is there. * Fails once PF state table is full. */ int udptest(int s) { int i, ret; for (i = 0; i <= 3; i++) { if (write(s, "X", 1) == 1) ret = 1; else ret = -1; } return (ret); } void set_common_sockopts(int s) { int x = 1; #ifdef TCP_MD5SIG if (Sflag) { if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, &x, sizeof(x)) == -1) err(1, "setsockopt"); } #endif if (Dflag) { if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof(x)) == -1) err(1, "setsockopt"); } if (Tflag != -1) { if (setsockopt(s, IPPROTO_IP, IP_TOS, &Tflag, sizeof(Tflag)) == -1) err(1, "set IP ToS"); } if (Iflag) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &Iflag, sizeof(Iflag)) == -1) err(1, "set TCP receive buffer size"); } if (Oflag) { if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &Oflag, sizeof(Oflag)) == -1) err(1, "set TCP send buffer size"); } } int map_tos(char *s, int *val) { /* DiffServ Codepoints and other TOS mappings */ const struct toskeywords { const char *keyword; int val; } *t, toskeywords[] = { { "af11", IPTOS_DSCP_AF11 }, { "af12", IPTOS_DSCP_AF12 }, { "af13", IPTOS_DSCP_AF13 }, { "af21", IPTOS_DSCP_AF21 }, { "af22", IPTOS_DSCP_AF22 }, { "af23", IPTOS_DSCP_AF23 }, { "af31", IPTOS_DSCP_AF31 }, { "af32", IPTOS_DSCP_AF32 }, { "af33", IPTOS_DSCP_AF33 }, { "af41", IPTOS_DSCP_AF41 }, { "af42", IPTOS_DSCP_AF42 }, { "af43", IPTOS_DSCP_AF43 }, { "critical", IPTOS_PREC_CRITIC_ECP }, { "cs0", IPTOS_DSCP_CS0 }, { "cs1", IPTOS_DSCP_CS1 }, { "cs2", IPTOS_DSCP_CS2 }, { "cs3", IPTOS_DSCP_CS3 }, { "cs4", IPTOS_DSCP_CS4 }, { "cs5", IPTOS_DSCP_CS5 }, { "cs6", IPTOS_DSCP_CS6 }, { "cs7", IPTOS_DSCP_CS7 }, { "ef", IPTOS_DSCP_EF }, { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, { "lowdelay", IPTOS_LOWDELAY }, { "netcontrol", IPTOS_PREC_NETCONTROL }, { "reliability", IPTOS_RELIABILITY }, { "throughput", IPTOS_THROUGHPUT }, { NULL, -1 }, }; for (t = toskeywords; t->keyword != NULL; t++) { if (strcmp(s, t->keyword) == 0) { *val = t->val; return (1); } } return (0); } void report_connect(const struct sockaddr *sa, socklen_t salen) { char remote_host[NI_MAXHOST]; char remote_port[NI_MAXSERV]; int herr; int flags = NI_NUMERICSERV; if (nflag) flags |= NI_NUMERICHOST; if ((herr = getnameinfo(sa, salen, remote_host, sizeof(remote_host), remote_port, sizeof(remote_port), flags)) != 0) { if (herr == EAI_SYSTEM) err(1, "getnameinfo"); else errx(1, "getnameinfo: %s", gai_strerror(herr)); } fprintf(stderr, "Connection from %s %s " "received!\n", remote_host, remote_port); } void help(void) { usage(0); fprintf(stderr, "\tCommand Summary:\n\ \t-4 Use IPv4\n\ \t-6 Use IPv6\n\ \t-D Enable the debug socket option\n\ \t-d Detach from stdin\n\ \t-F Pass socket fd\n\ \t-h This help text\n\ \t-I length TCP receive buffer length\n\ \t-i secs\t Delay interval for lines sent, ports scanned\n\ \t-k Keep inbound sockets open for multiple connects\n\ \t-l Listen mode, for inbound connects\n\ \t-N Shutdown the network socket after EOF on stdin\n\ \t-n Suppress name/port resolutions\n\ \t-O length TCP send buffer length\n\ \t-P proxyuser\tUsername for proxy authentication\n\ \t-p port\t Specify local port for remote connects\n\ \t-r Randomize remote ports\n\ \t-S Enable the TCP MD5 signature option\n\ \t-s addr\t Local source address\n\ \t-T toskeyword\tSet IP Type of Service\n\ \t-t Answer TELNET negotiation\n\ \t-U Use UNIX domain socket\n\ \t-u UDP mode\n\ \t-V rtable Specify alternate routing table\n\ \t-v Verbose\n\ \t-w secs\t Timeout for connects and final net reads\n\ \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ \t-x addr[:port]\tSpecify proxy address and port\n\ \t-z Zero-I/O mode [used for scanning]\n\ Port numbers can be individual or ranges: lo-hi [inclusive]\n"); exit(1); } void usage(int ret) { fprintf(stderr, "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n" "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" "\t [-x proxy_address[:port]] [destination] [port]\n"); if (ret) exit(1); } /* *** src/usr.bin/nc/socks.c *** */ /* $OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $ */ /* * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. * Copyright (c) 2004, 2005 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 #include #include #include #include #include #include #include #include #include #include #define SOCKS_PORT "1080" #define HTTP_PROXY_PORT "3128" #define HTTP_MAXHDRS 64 #define SOCKS_V5 5 #define SOCKS_V4 4 #define SOCKS_NOAUTH 0 #define SOCKS_NOMETHOD 0xff #define SOCKS_CONNECT 1 #define SOCKS_IPV4 1 #define SOCKS_DOMAIN 3 #define SOCKS_IPV6 4 int remote_connect(const char *, const char *, struct addrinfo); int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *, struct addrinfo, int, const char *); static int decode_addrport(const char *h, const char *p, struct sockaddr *addr, socklen_t addrlen, int v4only, int numeric) { int r; struct addrinfo hints, *res; bzero(&hints, sizeof(hints)); hints.ai_family = v4only ? PF_INET : PF_UNSPEC; hints.ai_flags = numeric ? AI_NUMERICHOST : 0; hints.ai_socktype = SOCK_STREAM; r = getaddrinfo(h, p, &hints, &res); /* Don't fatal when attempting to convert a numeric address */ if (r != 0) { if (!numeric) { errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p, gai_strerror(r)); } return (-1); } if (addrlen < res->ai_addrlen) { freeaddrinfo(res); errx(1, "internal error: addrlen < res->ai_addrlen"); } memcpy(addr, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); return (0); } static int proxy_read_line(int fd, char *buf, size_t bufsz) { size_t off; for(off = 0;;) { if (off >= bufsz) errx(1, "proxy read too long"); if (atomicio(read, fd, buf + off, 1) != 1) err(1, "proxy read"); /* Skip CR */ if (buf[off] == '\r') continue; if (buf[off] == '\n') { buf[off] = '\0'; break; } off++; } return (off); } static const char * getproxypass(const char *proxyuser, const char *proxyhost) { char prompt[512]; static char pw[256]; snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ", proxyuser, proxyhost); if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL) errx(1, "Unable to read proxy passphrase"); return (pw); } int socks_connect(const char *host, const char *port, struct addrinfo hints __attribute__ ((__unused__)), const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, int socksv, const char *proxyuser) { int proxyfd, r, authretry = 0; size_t hlen, wlen = 0; unsigned char buf[1024]; size_t cnt; struct sockaddr_storage addr; struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; in_port_t serverport; const char *proxypass = NULL; if (proxyport == NULL) proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; /* Abuse API to lookup port */ if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr, sizeof(addr), 1, 1) == -1) errx(1, "unknown port \"%.64s\"", port); serverport = in4->sin_port; again: if (authretry++ > 3) errx(1, "Too many authentication failures"); proxyfd = remote_connect(proxyhost, proxyport, proxyhints); if (proxyfd < 0) return (-1); if (socksv == 5) { if (decode_addrport(host, port, (struct sockaddr *)&addr, sizeof(addr), 0, 1) == -1) addr.ss_family = 0; /* used in switch below */ /* Version 5, one method: no authentication */ buf[0] = SOCKS_V5; buf[1] = 1; buf[2] = SOCKS_NOAUTH; cnt = atomicio(vwrite, proxyfd, buf, 3); if (cnt != 3) err(1, "write failed (%zu/3)", cnt); cnt = atomicio(read, proxyfd, buf, 2); if (cnt != 2) err(1, "read failed (%zu/3)", cnt); if (buf[1] == SOCKS_NOMETHOD) errx(1, "authentication method negotiation failed"); switch (addr.ss_family) { case 0: /* Version 5, connect: domain name */ /* Max domain name length is 255 bytes */ hlen = strlen(host); if (hlen > 255) errx(1, "host name too long for SOCKS5"); buf[0] = SOCKS_V5; buf[1] = SOCKS_CONNECT; buf[2] = 0; buf[3] = SOCKS_DOMAIN; buf[4] = hlen; memcpy(buf + 5, host, hlen); memcpy(buf + 5 + hlen, &serverport, sizeof serverport); wlen = 7 + hlen; break; case AF_INET: /* Version 5, connect: IPv4 address */ buf[0] = SOCKS_V5; buf[1] = SOCKS_CONNECT; buf[2] = 0; buf[3] = SOCKS_IPV4; memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port); wlen = 10; break; case AF_INET6: /* Version 5, connect: IPv6 address */ buf[0] = SOCKS_V5; buf[1] = SOCKS_CONNECT; buf[2] = 0; buf[3] = SOCKS_IPV6; memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr); memcpy(buf + 20, &in6->sin6_port, sizeof in6->sin6_port); wlen = 22; break; default: errx(1, "internal error: silly AF"); } cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) err(1, "write failed (%zu/%zu)", cnt, wlen); cnt = atomicio(read, proxyfd, buf, 4); if (cnt != 4) err(1, "read failed (%zu/4)", cnt); if (buf[1] != 0) errx(1, "connection failed, SOCKS error %d", buf[1]); switch (buf[3]) { case SOCKS_IPV4: cnt = atomicio(read, proxyfd, buf + 4, 6); if (cnt != 6) err(1, "read failed (%zu/6)", cnt); break; case SOCKS_IPV6: cnt = atomicio(read, proxyfd, buf + 4, 18); if (cnt != 18) err(1, "read failed (%zu/18)", cnt); break; default: errx(1, "connection failed, unsupported address type"); } } else if (socksv == 4) { /* This will exit on lookup failure */ decode_addrport(host, port, (struct sockaddr *)&addr, sizeof(addr), 1, 0); /* Version 4 */ buf[0] = SOCKS_V4; buf[1] = SOCKS_CONNECT; /* connect */ memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); buf[8] = 0; /* empty username */ wlen = 9; cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) err(1, "write failed (%zu/%zu)", cnt, wlen); cnt = atomicio(read, proxyfd, buf, 8); if (cnt != 8) err(1, "read failed (%zu/8)", cnt); if (buf[1] != 90) errx(1, "connection failed, SOCKS error %d", buf[1]); } else if (socksv == -1) { /* HTTP proxy CONNECT */ /* Disallow bad chars in hostname */ if (strcspn(host, "\r\n\t []:") != strlen(host)) errx(1, "Invalid hostname"); /* Try to be sane about numeric IPv6 addresses */ if (strchr(host, ':') != NULL) { r = snprintf(buf, sizeof(buf), "CONNECT [%s]:%d HTTP/1.0\r\n", host, ntohs(serverport)); } else { r = snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n", host, ntohs(serverport)); } if (r == -1 || (size_t)r >= sizeof(buf)) errx(1, "hostname too long"); r = strlen(buf); cnt = atomicio(vwrite, proxyfd, buf, r); if (cnt != (size_t)r) err(1, "write failed (%zu/%d)", cnt, r); if (authretry > 1) { char resp[1024]; proxypass = getproxypass(proxyuser, proxyhost); r = snprintf(buf, sizeof(buf), "%s:%s", proxyuser, proxypass); if (r == -1 || (size_t)r >= sizeof(buf) || b64_ntop(buf, strlen(buf), resp, sizeof(resp)) == -1) errx(1, "Proxy username/password too long"); r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " "Basic %s\r\n", resp); if (r == -1 || (size_t)r >= sizeof(buf)) errx(1, "Proxy auth response too long"); r = strlen(buf); if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != (size_t)r) err(1, "write failed (%zu/%d)", cnt, r); } /* Terminate headers */ if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) err(1, "write failed (2/%d)", r); /* Read status reply */ proxy_read_line(proxyfd, buf, sizeof(buf)); if (proxyuser != NULL && strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { if (authretry > 1) { fprintf(stderr, "Proxy authentication " "failed\n"); } close(proxyfd); goto again; } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && strncmp(buf, "HTTP/1.1 200 ", 12) != 0) errx(1, "Proxy error: \"%s\"", buf); /* Headers continue until we hit an empty line */ for (r = 0; r < HTTP_MAXHDRS; r++) { proxy_read_line(proxyfd, buf, sizeof(buf)); if (*buf == '\0') break; } if (*buf != '\0') errx(1, "Too many proxy headers received"); } else errx(1, "Unknown proxy protocol %d", socksv); return (proxyfd); } openssh-7.2p2/regress/portnum.sh010064400017500001750000000011601267006270000151620ustar00djmdjm# $OpenBSD: portnum.sh,v 1.2 2013/05/17 10:34:30 dtucker Exp $ # Placed in the Public Domain. tid="port number parsing" badport() { port=$1 verbose "$tid: invalid port $port" if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then fail "$tid accepted invalid port $port" fi } goodport() { port=$1 verbose "$tid: valid port $port" if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then : else fail "$tid rejected valid port $port" fi } badport 0 badport 65536 badport 131073 badport 2000blah badport blah2000 goodport 1 goodport 22 goodport 2222 goodport 22222 goodport 65535 openssh-7.2p2/regress/principals-command.sh010064400017500001750000000115311267006270000172410ustar00djmdjm# $OpenBSD: principals-command.sh,v 1.1 2015/05/21 06:44:25 djm Exp $ # Placed in the Public Domain. tid="authorized principals command" rm -f $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak if test -z "$SUDO" ; then echo "skipped (SUDO not set)" echo "need SUDO to create file in /var/run, test won't work without" exit 0 fi # Establish a AuthorizedPrincipalsCommand in /var/run where it will have # acceptable directory permissions. PRINCIPALS_CMD="/var/run/principals_command_${LOGNAME}" cat << _EOF | $SUDO sh -c "cat > '$PRINCIPALS_CMD'" #!/bin/sh test "x\$1" != "x${LOGNAME}" && exit 1 test -f "$OBJ/authorized_principals_${LOGNAME}" && exec cat "$OBJ/authorized_principals_${LOGNAME}" _EOF test $? -eq 0 || fatal "couldn't prepare principals command" $SUDO chmod 0755 "$PRINCIPALS_CMD" if ! $OBJ/check-perm -m keys-command $PRINCIPALS_CMD ; then echo "skipping: $PRINCIPALS_CMD is unsuitable as " \ "AuthorizedPrincipalsCommand" $SUDO rm -f $PRINCIPALS_CMD exit 0 fi # Create a CA key and a user certificate. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key || \ fatal "ssh-keygen of user_ca_key failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/cert_user_key || \ fatal "ssh-keygen of cert_user_key failed" ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key || \ fatal "couldn't sign cert_user_key" if [ -x $PRINCIPALS_CMD ]; then # Test explicitly-specified principals for privsep in yes no ; do _prefix="privsep $privsep" # Setup for AuthorizedPrincipalsCommand rm -f $OBJ/authorized_keys_$USER ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" echo "AuthorizedKeysFile none" echo "AuthorizedPrincipalsCommand $PRINCIPALS_CMD %u" echo "AuthorizedPrincipalsCommandUser ${LOGNAME}" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" ) > $OBJ/sshd_proxy # XXX test missing command # XXX test failing command # Empty authorized_principals verbose "$tid: ${_prefix} empty authorized_principals" echo > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Wrong authorized_principals verbose "$tid: ${_prefix} wrong authorized_principals" echo gregorsamsa > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Correct authorized_principals verbose "$tid: ${_prefix} correct authorized_principals" echo mekmitasdigoat > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi # authorized_principals with bad key option verbose "$tid: ${_prefix} authorized_principals bad key opt" echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # authorized_principals with command=false verbose "$tid: ${_prefix} authorized_principals command=false" echo 'command="false" mekmitasdigoat' > \ $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # authorized_principals with command=true verbose "$tid: ${_prefix} authorized_principals command=true" echo 'command="true" mekmitasdigoat' > \ $OBJ/authorized_principals_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi # Setup for principals= key option rm -f $OBJ/authorized_principals_$USER ( cat $OBJ/sshd_proxy_bak echo "UsePrivilegeSeparation $privsep" ) > $OBJ/sshd_proxy # Wrong principals list verbose "$tid: ${_prefix} wrong principals key option" ( printf 'cert-authority,principals="gregorsamsa" ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then fail "ssh cert connect succeeded unexpectedly" fi # Correct principals list verbose "$tid: ${_prefix} correct principals key option" ( printf 'cert-authority,principals="mekmitasdigoat" ' cat $OBJ/user_ca_key.pub ) > $OBJ/authorized_keys_$USER ${SSH} -2i $OBJ/cert_user_key \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh cert connect failed" fi done else echo "SKIPPED: $PRINCIPALS_COMMAND not executable " \ "(/var/run mounted noexec?)" fi openssh-7.2p2/regress/proto-mismatch.sh010064400017500001750000000007311267006270000164270ustar00djmdjm# $OpenBSD: proto-mismatch.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="protocol version mismatch" mismatch () { server=$1 client=$2 banner=`echo ${client} | ${SSHD} -o "Protocol=${server}" -i -f ${OBJ}/sshd_proxy` r=$? trace "sshd prints ${banner}" if [ $r -ne 255 ]; then fail "sshd prints ${banner} and accepts connect with version ${client}" fi } mismatch 2 SSH-1.5-HALLO if ssh_version 1; then mismatch 1 SSH-2.0-HALLO fi openssh-7.2p2/regress/proto-version.sh010064400017500001750000000012441267006270000163070ustar00djmdjm# $OpenBSD: proto-version.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd version with different protocol combinations" # we just start sshd in inetd mode and check the banner check_version () { version=$1 expect=$2 banner=`printf '' | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy` case ${banner} in SSH-1.99-*) proto=199 ;; SSH-2.0-*) proto=20 ;; SSH-1.5-*) proto=15 ;; *) proto=0 ;; esac if [ ${expect} -ne ${proto} ]; then fail "wrong protocol version ${banner} for ${version}" fi } check_version 2 20 if ssh_version 1; then check_version 2,1 199 check_version 1,2 199 check_version 1 15 fi openssh-7.2p2/regress/proxy-connect.sh010064400017500001750000000017151267006270000162740ustar00djmdjm# $OpenBSD: proxy-connect.sh,v 1.9 2016/02/17 02:24:17 djm Exp $ # Placed in the Public Domain. tid="proxy connect" mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig for ps in no yes; do cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy for p in ${SSH_PROTOCOLS}; do for c in no yes; do verbose "plain username protocol $p privsep=$ps comp=$c" opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'` if [ $? -ne 0 ]; then fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed" fi if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c: " \ "$SSH_CONNECTION" fi done done done for p in ${SSH_PROTOCOLS}; do verbose "username with style protocol $p" ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ fail "ssh proxyconnect protocol $p failed" done openssh-7.2p2/regress/putty-ciphers.sh010064400017500001750000000012761267006270000163060ustar00djmdjm# $OpenBSD: putty-ciphers.sh,v 1.4 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="putty ciphers" if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then echo "putty interop tests not enabled" exit 0 fi for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do verbose "$tid: cipher $c" cp ${OBJ}/.putty/sessions/localhost_proxy \ ${OBJ}/.putty/sessions/cipher_$c echo "Cipher=$c" >> ${OBJ}/.putty/sessions/cipher_$c rm -f ${COPY} env HOME=$PWD ${PLINK} -load cipher_$c -batch -i putty.rsa2 \ 127.0.0.1 cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" done rm -f ${COPY} openssh-7.2p2/regress/putty-kex.sh010064400017500001750000000010631267006270000154320ustar00djmdjm# $OpenBSD: putty-kex.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="putty KEX" if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then echo "putty interop tests not enabled" exit 0 fi for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do verbose "$tid: kex $k" cp ${OBJ}/.putty/sessions/localhost_proxy \ ${OBJ}/.putty/sessions/kex_$k echo "KEX=$k" >> ${OBJ}/.putty/sessions/kex_$k env HOME=$PWD ${PLINK} -load kex_$k -batch -i putty.rsa2 \ 127.0.0.1 true if [ $? -ne 0 ]; then fail "KEX $k failed" fi done openssh-7.2p2/regress/putty-transfer.sh010064400017500001750000000021451267006270000164710ustar00djmdjm# $OpenBSD: putty-transfer.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="putty transfer data" if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then echo "putty interop tests not enabled" exit 0 fi # XXX support protocol 1 too for p in 2; do for c in 0 1 ; do verbose "$tid: proto $p compression $c" rm -f ${COPY} cp ${OBJ}/.putty/sessions/localhost_proxy \ ${OBJ}/.putty/sessions/compression_$c echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k env HOME=$PWD ${PLINK} -load compression_$c -batch \ -i putty.rsa$p 127.0.0.1 cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" for s in 10 100 1k 32k 64k 128k 256k; do trace "proto $p compression $c dd-size ${s}" rm -f ${COPY} dd if=$DATA obs=${s} 2> /dev/null | \ env HOME=$PWD ${PLINK} -load compression_$c \ -batch -i putty.rsa$p 127.0.0.1 \ "cat > ${COPY}" if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp $DATA ${COPY} || fail "corrupted copy" done done done rm -f ${COPY} openssh-7.2p2/regress/reconfigure.sh010064400017500001750000000017441267006270000157760ustar00djmdjm# $OpenBSD: reconfigure.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple connect after reconfigure" # we need the full path to sshd for -HUP if test "x$USE_VALGRIND" = "x" ; then case $SSHD in /*) # full path is OK ;; *) # otherwise make fully qualified SSHD=$OBJ/$SSHD esac fi start_sshd trace "connect before restart" for p in ${SSH_PROTOCOLS} ; do ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed before reconfigure" fi done PID=`$SUDO cat $PIDFILE` rm -f $PIDFILE $SUDO kill -HUP $PID trace "wait for sshd to restart" i=0; while [ ! -f $PIDFILE -a $i -lt 10 ]; do i=`expr $i + 1` sleep $i done test -f $PIDFILE || fatal "sshd did not restart" trace "connect after restart" for p in ${SSH_PROTOCOLS} ; do ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed after reconfigure" fi done openssh-7.2p2/regress/reexec.sh010064400017500001750000000023741267006270000147410ustar00djmdjm# $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="reexec tests" SSHD_ORIG=$SSHD SSHD_COPY=$OBJ/sshd # Start a sshd and then delete it start_sshd_copy () { cp $SSHD_ORIG $SSHD_COPY SSHD=$SSHD_COPY start_sshd SSHD=$SSHD_ORIG } # Do basic copy tests copy_tests () { rm -f ${COPY} for p in ${SSH_PROTOCOLS} ; do verbose "$tid: proto $p" ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" rm -f ${COPY} done } verbose "test config passing" cp $OBJ/sshd_config $OBJ/sshd_config.orig start_sshd echo "InvalidXXX=no" >> $OBJ/sshd_config copy_tests $SUDO kill `$SUDO cat $PIDFILE` rm -f $PIDFILE cp $OBJ/sshd_config.orig $OBJ/sshd_config # cygwin can't fork a deleted binary if [ "$os" != "cygwin" ]; then verbose "test reexec fallback" start_sshd_copy rm -f $SSHD_COPY copy_tests $SUDO kill `$SUDO cat $PIDFILE` rm -f $PIDFILE verbose "test reexec fallback without privsep" cp $OBJ/sshd_config.orig $OBJ/sshd_config echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config start_sshd_copy rm -f $SSHD_COPY copy_tests $SUDO kill `$SUDO cat $PIDFILE` rm -f $PIDFILE fi openssh-7.2p2/regress/rekey.sh010064400017500001750000000101721267006270000146000ustar00djmdjm# $OpenBSD: rekey.sh,v 1.17 2016/01/29 05:18:15 dtucker Exp $ # Placed in the Public Domain. tid="rekey" LOG=${TEST_SSH_LOGFILE} rm -f ${LOG} cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak # Test rekeying based on data volume only. # Arguments will be passed to ssh. ssh_data_rekeying() { _kexopt=$1 ; shift _opts="$@" if ! test -z "$_kexopts" ; then cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "$_kexopt" >> $OBJ/sshd_proxy _opts="$_opts -o$_kexopt" fi rm -f ${COPY} ${LOG} _opts="$_opts -oCompression=no" ${SSH} <${DATA} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" if [ $? -ne 0 ]; then fail "ssh failed ($@)" fi cmp ${DATA} ${COPY} || fail "corrupted copy ($@)" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occured ($@)" fi } increase_datafile_size 300 opts="" for i in `${SSH} -Q kex`; do opts="$opts KexAlgorithms=$i" done for i in `${SSH} -Q cipher`; do opts="$opts Ciphers=$i" done for i in `${SSH} -Q mac`; do opts="$opts MACs=$i" done for opt in $opts; do verbose "client rekey $opt" ssh_data_rekeying "$opt" -oRekeyLimit=256k done # AEAD ciphers are magical so test with all KexAlgorithms if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then for c in `${SSH} -Q cipher-auth`; do for kex in `${SSH} -Q kex`; do verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done done fi for s in 16 1k 128k 256k; do verbose "client rekeylimit ${s}" ssh_data_rekeying "" -oCompression=no -oRekeyLimit=$s done for s in 5 10; do verbose "client rekeylimit default ${s}" rm -f ${COPY} ${LOG} ${SSH} < ${DATA} -oCompression=no -oRekeyLimit="default $s" -F \ $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 3" if [ $? -ne 0 ]; then fail "ssh failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occured" fi done for s in 5 10; do verbose "client rekeylimit default ${s} no data" rm -f ${COPY} ${LOG} ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \ $OBJ/ssh_proxy somehost "sleep $s;sleep 3" if [ $? -ne 0 ]; then fail "ssh failed" fi n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occured" fi done for s in 16 1k 128k 256k; do verbose "server rekeylimit ${s}" cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "rekeylimit ${s}" >>$OBJ/sshd_proxy rm -f ${COPY} ${LOG} ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "cat ${DATA}" \ > ${COPY} if [ $? -ne 0 ]; then fail "ssh failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occured" fi done for s in 5 10; do verbose "server rekeylimit default ${s} no data" cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy rm -f ${COPY} ${LOG} ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3" if [ $? -ne 0 ]; then fail "ssh failed" fi n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occured" fi done verbose "rekeylimit parsing" for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do case $size in 16) bytes=16 ;; 1k|1K) bytes=1024 ;; 1m|1M) bytes=1048576 ;; 1g|1G) bytes=1073741824 ;; 4g|4G) bytes=4294967296 ;; 8g|8G) bytes=8589934592 ;; esac case $time in 1) seconds=1 ;; 1m|1M) seconds=60 ;; 1h|1H) seconds=3600 ;; 1d|1D) seconds=86400 ;; 1w|1W) seconds=604800 ;; esac b=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ awk '/rekeylimit/{print $2}'` s=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ awk '/rekeylimit/{print $3}'` if [ "$bytes" != "$b" ]; then fatal "rekeylimit size: expected $bytes bytes got $b" fi if [ "$seconds" != "$s" ]; then fatal "rekeylimit time: expected $time seconds got $s" fi done done rm -f ${COPY} ${DATA} openssh-7.2p2/regress/rsa_openssh.prv010064400017500001750000000015631267006270000162060ustar00djmdjm-----BEGIN RSA PRIVATE KEY----- MIICWgIBAAKBgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko +dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3 xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQIDAQAB An8nH5VzvHkMbSqJ6eOYDsVwomRvYbH5IEaYl1x6VATITNvAu9kUdQ4NsSpuMc+7 Jj9gKZvmO1y2YCKc0P/iO+i/eV0L+yQh1Rw18jQZll+12T+LZrKRav03YNvMx0gN wqWY48Kt6hv2/N/ebQzKRe79+D0t2cTh92hT7xENFLIBAkEBGnoGKFjAUkJCwO1V mzpUqMHpRZVOrqP9hUmPjzNJ5oBPFGe4+h1hoSRFOAzaNuZt8ssbqaLCkzB8bfzj qhZqAQJBANZekuUpp8iBLeLSagw5FkcPwPzq6zfExbhvsZXb8Bo/4SflNs4JHXwI 7SD9Z8aJLvM4uQ/5M70lblDMQ40i3o0CQQDIJvBYBFL5tlOgakq/O7yi+wt0L5BZ 9H79w5rCSAA0IHRoK/qI1urHiHC3f3vbbLk5UStfrqEaND/mm0shyNIBAkBLsYdC /ctt5Bc0wUGK4Vl5bBmj9LtrrMJ4FpBpLwj/69BwCuKoK9XKZ0h73p6XHveCEGRg PIlFX4MtaoLrwgU9AkBV2k4dgIws+X8YX65EsyyFjnlDqX4x0nSOjQB1msIKfHBr dh5XLDBTTCxnKhMJ0Yx/opgOvf09XHBFwaQntR5i -----END RSA PRIVATE KEY----- openssh-7.2p2/regress/rsa_openssh.pub010064400017500001750000000003251267006270000161600ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko+dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQ== openssh-7.2p2/regress/rsa_ssh2.prv010064400017500001750000000016341267006270000154050ustar00djmdjm---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- Subject: ssh-keygen test Comment: "1024-bit rsa, Sat Jun 23 2001 12:21:26 -0400" P2/56wAAAi4AAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS 1wa2NzMXYyLW9hZXB9fQAAAARub25lAAAB3wAAAdsAAAARAQABAAAD9icflXO8eQxtKonp 45gOxXCiZG9hsfkgRpiXXHpUBMhM28C72RR1Dg2xKm4xz7smP2Apm+Y7XLZgIpzQ/+I76L 95XQv7JCHVHDXyNBmWX7XZP4tmspFq/Tdg28zHSA3CpZjjwq3qG/b8395tDMpF7v34PS3Z xOH3aFPvEQ0UsgEAAAQA7IpcCnGijesEjDXdVoEPfh0akBJA9JAk1bba2sxrtDoQVN1JKP nRQ9SKdAsXV5jduSUFsTmBe4fznLvD948790U1/O8SkdGM5V0y1/ki7Rf8knm0t8Vj65X0 VA4YdN4UeVfvMcb78vcInT2CsP6CLcBkrnjrBKtS03Mwg79nQI0AAAH/VdpOHYCMLPl/GF +uRLMshY55Q6l+MdJ0jo0AdZrCCnxwa3YeVywwU0wsZyoTCdGMf6KYDr39PVxwRcGkJ7Ue YgAAAgDWXpLlKafIgS3i0moMORZHD8D86us3xMW4b7GV2/AaP+En5TbOCR18CO0g/WfGiS 7zOLkP+TO9JW5QzEONIt6NAAACAQEaegYoWMBSQkLA7VWbOlSowelFlU6uo/2FSY+PM0nm gE8UZ7j6HWGhJEU4DNo25m3yyxuposKTMHxt/OOqFmoB ---- END SSH2 ENCRYPTED PRIVATE KEY ---- --- openssh-7.2p2/regress/scp-ssh-wrapper.sh010064400017500001750000000016221267006270000165170ustar00djmdjm#!/bin/sh # $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $ # Placed in the Public Domain. printname () { NAME=$1 save_IFS=$IFS IFS=/ set -- `echo "$NAME"` IFS="$save_IFS" while [ $# -ge 1 ] ; do if [ "x$1" != "x" ]; then echo "D0755 0 $1" fi shift; done } # Discard all but last argument. We use arg later. while test "x$1" != "x"; do arg="$1" shift done BAD="../../../../../../../../../../../../../${DIR}/dotpathdir" case "$SCPTESTMODE" in badserver_0) echo "D0755 0 /${DIR}/rootpathdir" echo "C755 2 rootpathfile" echo "X" ;; badserver_1) echo "D0755 0 $BAD" echo "C755 2 file" echo "X" ;; badserver_2) echo "D0755 0 $BAD" echo "C755 2 file" echo "X" ;; badserver_3) printname $BAD echo "C755 2 file" echo "X" ;; badserver_4) printname $BAD echo "D0755 0 .." echo "C755 2 file" echo "X" ;; *) set -- $arg shift exec $SCP "$@" ;; esac openssh-7.2p2/regress/scp.sh010064400017500001750000000070001267006270000142420ustar00djmdjm# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $ # Placed in the Public Domain. tid="scp" #set -x # Figure out if diff understands "-N" if diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then DIFFOPT="-rN" else DIFFOPT="-r" fi COPY2=${OBJ}/copy2 DIR=${COPY}.dd DIR2=${COPY}.dd2 SRC=`dirname ${SCRIPT}` cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp chmod 755 ${OBJ}/scp-ssh-wrapper.scp scpopts="-q -S ${OBJ}/scp-ssh-wrapper.scp" export SCP # used in scp-ssh-wrapper.scp scpclean() { rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} mkdir ${DIR} ${DIR2} } verbose "$tid: simple copy local file to local file" scpclean $SCP $scpopts ${DATA} ${COPY} || fail "copy failed" cmp ${DATA} ${COPY} || fail "corrupted copy" verbose "$tid: simple copy local file to remote file" scpclean $SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed" cmp ${DATA} ${COPY} || fail "corrupted copy" verbose "$tid: simple copy remote file to local file" scpclean $SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed" cmp ${DATA} ${COPY} || fail "corrupted copy" verbose "$tid: simple copy local file to remote dir" scpclean cp ${DATA} ${COPY} $SCP $scpopts ${COPY} somehost:${DIR} || fail "copy failed" cmp ${COPY} ${DIR}/copy || fail "corrupted copy" verbose "$tid: simple copy local file to local dir" scpclean cp ${DATA} ${COPY} $SCP $scpopts ${COPY} ${DIR} || fail "copy failed" cmp ${COPY} ${DIR}/copy || fail "corrupted copy" verbose "$tid: simple copy remote file to local dir" scpclean cp ${DATA} ${COPY} $SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed" cmp ${COPY} ${DIR}/copy || fail "corrupted copy" verbose "$tid: recursive local dir to remote dir" scpclean rm -rf ${DIR2} cp ${DATA} ${DIR}/copy $SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed" diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" verbose "$tid: recursive local dir to local dir" scpclean rm -rf ${DIR2} cp ${DATA} ${DIR}/copy $SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed" diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" verbose "$tid: recursive remote dir to local dir" scpclean rm -rf ${DIR2} cp ${DATA} ${DIR}/copy $SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed" diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" verbose "$tid: shell metacharacters" scpclean (cd ${DIR} && \ touch '`touch metachartest`' && \ $SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \ [ ! -f metachartest ] ) || fail "shell metacharacters" if [ ! -z "$SUDO" ]; then verbose "$tid: skipped file after scp -p with failed chown+utimes" scpclean cp -p ${DATA} ${DIR}/copy cp -p ${DATA} ${DIR}/copy2 cp ${DATA} ${DIR2}/copy chmod 660 ${DIR2}/copy $SUDO chown root ${DIR2}/copy $SCP -p $scpopts somehost:${DIR}/\* ${DIR2} >/dev/null 2>&1 $SUDO diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" $SUDO rm ${DIR2}/copy fi for i in 0 1 2 3 4; do verbose "$tid: disallow bad server #$i" SCPTESTMODE=badserver_$i export DIR SCPTESTMODE scpclean $SCP $scpopts somehost:${DATA} ${DIR} >/dev/null 2>/dev/null [ -d {$DIR}/rootpathdir ] && fail "allows dir relative to root dir" [ -d ${DIR}/dotpathdir ] && fail "allows dir creation in non-recursive mode" scpclean $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" done verbose "$tid: detect non-directory target" scpclean echo a > ${COPY} echo b > ${COPY2} $SCP $scpopts ${DATA} ${COPY} ${COPY2} cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target" scpclean rm -f ${OBJ}/scp-ssh-wrapper.scp openssh-7.2p2/regress/setuid-allowed.c010064400017500001750000000026721267006270000162210ustar00djmdjm/* * Copyright (c) 2013 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* $OpenBSD$ */ #include "includes.h" #include #ifdef HAVE_SYS_STATVFS_H # include #endif #include #include #include static void usage(void) { fprintf(stderr, "check-setuid [path]\n"); exit(1); } int main(int argc, char **argv) { const char *path = "."; struct statvfs sb; if (argc > 2) usage(); else if (argc == 2) path = argv[1]; if (statvfs(path, &sb) != 0) { /* Don't return an error if the host doesn't support statvfs */ if (errno == ENOSYS) return 0; fprintf(stderr, "statvfs for \"%s\" failed: %s\n", path, strerror(errno)); } return (sb.f_flag & ST_NOSUID) ? 1 : 0; } openssh-7.2p2/regress/sftp-badcmds.sh010064400017500001750000000043451267006270000160350ustar00djmdjm# $OpenBSD: sftp-badcmds.sh,v 1.6 2013/05/17 10:26:26 dtucker Exp $ # Placed in the Public Domain. tid="sftp invalid commands" DATA2=/bin/sh${EXEEXT} NONEXIST=/NONEXIST.$$ GLOBFILES=`(cd /bin;echo l*)` rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd rm -f ${COPY} verbose "$tid: get nonexistent" echo "get $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get nonexistent failed" test -f ${COPY} && fail "existing copy after get nonexistent" rm -f ${COPY}.dd/* verbose "$tid: glob get to nonexistent directory" echo "get /bin/l* $NONEXIST" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get nonexistent failed" for x in $GLOBFILES; do test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent" done rm -f ${COPY} verbose "$tid: put nonexistent" echo "put $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put nonexistent failed" test -f ${COPY} && fail "existing copy after put nonexistent" rm -f ${COPY}.dd/* verbose "$tid: glob put to nonexistent directory" echo "put /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put nonexistent failed" for x in $GLOBFILES; do test -f ${COPY}.dd/$x && fail "existing copy after nonexistent" done rm -f ${COPY} verbose "$tid: rename nonexistent" echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename nonexist failed" test -f ${COPY}.1 && fail "file exists after rename nonexistent" rm -rf ${COPY} ${COPY}.dd cp $DATA $COPY mkdir ${COPY}.dd verbose "$tid: rename target exists (directory)" echo "rename $COPY ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename target exists (directory) failed" test -f ${COPY} || fail "oldname missing after rename target exists (directory)" test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)" cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists (directory)" rm -f ${COPY}.dd/* rm -rf ${COPY} cp ${DATA2} ${COPY} verbose "$tid: glob put files to local file" echo "put /bin/l* $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 cmp ${DATA2} ${COPY} || fail "put successed when it should have failed" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd openssh-7.2p2/regress/sftp-batch.sh010064400017500001750000000022451267006270000155160ustar00djmdjm# $OpenBSD: sftp-batch.sh,v 1.5 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="sftp batchfile" BATCH=${OBJ}/sftp.bb rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* cat << EOF > ${BATCH}.pass.1 get $DATA $COPY put ${COPY} ${COPY}.1 rm ${COPY} -put ${COPY} ${COPY}.2 EOF cat << EOF > ${BATCH}.pass.2 # This is a comment # That was a blank line ls EOF cat << EOF > ${BATCH}.fail.1 get $DATA $COPY put ${COPY} ${COPY}.3 rm ${COPY}.* # The next command should fail put ${COPY}.3 ${COPY}.4 EOF cat << EOF > ${BATCH}.fail.2 # The next command should fail jajajajaja EOF verbose "$tid: good commands" ${SFTP} -b ${BATCH}.pass.1 -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "good commands failed" verbose "$tid: bad commands" ${SFTP} -b ${BATCH}.fail.1 -D ${SFTPSERVER} >/dev/null 2>&1 \ && fail "bad commands succeeded" verbose "$tid: comments and blanks" ${SFTP} -b ${BATCH}.pass.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "comments & blanks failed" verbose "$tid: junk command" ${SFTP} -b ${BATCH}.fail.2 -D ${SFTPSERVER} >/dev/null 2>&1 \ && fail "junk command succeeded" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* openssh-7.2p2/regress/sftp-chroot.sh010064400017500001750000000014711267006270000157330ustar00djmdjm# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $ # Placed in the Public Domain. tid="sftp in chroot" CHROOT=/var/run FILENAME=testdata_${USER} PRIVDATA=${CHROOT}/${FILENAME} if [ -z "$SUDO" ]; then echo "skipped: need SUDO to create file in /var/run, test won't work without" exit 0 fi if ! $OBJ/check-perm -m chroot "$CHROOT" ; then echo "skipped: $CHROOT is unsuitable as ChrootDirectory" exit 0 fi $SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \ fatal "create $PRIVDATA failed" start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /" verbose "test $tid: get" ${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \ >>$TEST_REGRESS_LOGFILE 2>&1 || \ fatal "Fetch ${FILENAME} failed" cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" $SUDO rm $PRIVDATA openssh-7.2p2/regress/sftp-cmds.sh010064400017500001750000000164511267006270000153670ustar00djmdjm# $OpenBSD: sftp-cmds.sh,v 1.14 2013/06/21 02:26:26 djm Exp $ # Placed in the Public Domain. # XXX - TODO: # - chmod / chown / chgrp # - -p flag for get & put tid="sftp commands" # test that these files are readable! for i in `(cd /bin;echo l*)` do if [ -r $i ]; then GLOBFILES="$GLOBFILES $i" fi done # Path with embedded quote QUOTECOPY=${COPY}".\"blah\"" QUOTECOPY_ARG=${COPY}'.\"blah\"' # File with spaces SPACECOPY="${COPY} this has spaces.txt" SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt" # File with glob metacharacters GLOBMETACOPY="${COPY} [metachar].txt" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 mkdir ${COPY}.dd verbose "$tid: lls" (echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ grep copy.dd >/dev/null 2>&1 || fail "lls failed" verbose "$tid: lls w/path" echo "lls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ grep copy.dd >/dev/null 2>&1 || fail "lls w/path failed" verbose "$tid: ls" echo "ls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "ls failed" # XXX always successful verbose "$tid: shell" echo "!echo hi there" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "shell failed" # XXX always successful verbose "$tid: pwd" echo "pwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "pwd failed" # XXX always successful verbose "$tid: lpwd" echo "lpwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lpwd failed" # XXX always successful verbose "$tid: quit" echo "quit" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "quit failed" # XXX always successful verbose "$tid: help" echo "help" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "help failed" # XXX always successful rm -f ${COPY} verbose "$tid: get" echo "get $DATA $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" rm -f ${COPY} verbose "$tid: get quoted" echo "get \"$DATA\" $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" if [ "$os" != "cygwin" ]; then rm -f ${QUOTECOPY} cp $DATA ${QUOTECOPY} verbose "$tid: get filename with quotes" echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes" rm -f ${QUOTECOPY} ${COPY} fi rm -f "$SPACECOPY" ${COPY} cp $DATA "$SPACECOPY" verbose "$tid: get filename with spaces" echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces" rm -f "$GLOBMETACOPY" ${COPY} cp $DATA "$GLOBMETACOPY" verbose "$tid: get filename with glob metacharacters" echo "get \"${GLOBMETACOPY}\" ${COPY}" | \ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed" cmp ${COPY} "$GLOBMETACOPY" || \ fail "corrupted copy after get with glob metacharacters" rm -f ${COPY}.dd/* verbose "$tid: get to directory" echo "get $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get" rm -f ${COPY}.dd/* verbose "$tid: glob get to directory" echo "get /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" done rm -f ${COPY}.dd/* verbose "$tid: get to local dir" (echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get" rm -f ${COPY}.dd/* verbose "$tid: glob get to local dir" (echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" done rm -f ${COPY} verbose "$tid: put" echo "put $DATA $COPY" | \ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA ${COPY} || fail "corrupted copy after put" if [ "$os" != "cygwin" ]; then rm -f ${QUOTECOPY} verbose "$tid: put filename with quotes" echo "put $DATA \"$QUOTECOPY_ARG\"" | \ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" fi rm -f "$SPACECOPY" verbose "$tid: put filename with spaces" echo "put $DATA ${SPACECOPY_ARG}" | \ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces" rm -f ${COPY}.dd/* verbose "$tid: put to directory" echo "put $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put" rm -f ${COPY}.dd/* verbose "$tid: glob put to directory" echo "put /bin/l? ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" done rm -f ${COPY}.dd/* verbose "$tid: put to local dir" (echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put" rm -f ${COPY}.dd/* verbose "$tid: glob put to local dir" (echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" done verbose "$tid: rename" echo "rename $COPY ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename failed" test -f ${COPY}.1 || fail "missing file after rename" cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" verbose "$tid: rename directory" echo "rename ${COPY}.dd ${COPY}.dd2" | \ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || \ fail "rename directory failed" test -d ${COPY}.dd && fail "oldname exists after rename directory" test -d ${COPY}.dd2 || fail "missing newname after rename directory" verbose "$tid: ln" echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" test -f ${COPY}.2 || fail "missing file after ln" cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after ln" verbose "$tid: ln -s" rm -f ${COPY}.2 echo "ln -s ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln -s failed" test -h ${COPY}.2 || fail "missing file after ln -s" verbose "$tid: mkdir" echo "mkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "mkdir failed" test -d ${COPY}.dd || fail "missing directory after mkdir" # XXX do more here verbose "$tid: chdir" echo "chdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "chdir failed" verbose "$tid: rmdir" echo "rmdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rmdir failed" test -d ${COPY}.1 && fail "present directory after rmdir" verbose "$tid: lmkdir" echo "lmkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lmkdir failed" test -d ${COPY}.dd || fail "missing directory after lmkdir" # XXX do more here verbose "$tid: lchdir" echo "lchdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lchdir failed" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY" openssh-7.2p2/regress/sftp-glob.sh010064400017500001750000000047401267006270000153620ustar00djmdjm# $OpenBSD: sftp-glob.sh,v 1.4 2009/08/13 01:11:55 djm Exp $ # Placed in the Public Domain. tid="sftp glob" config_defined FILESYSTEM_NO_BACKSLASH && nobs="not supported on this platform" sftp_ls() { target=$1 errtag=$2 expected=$3 unexpected=$4 skip=$5 if test "x$skip" != "x" ; then verbose "$tid: $errtag (skipped: $skip)" return fi verbose "$tid: $errtag" printf "ls -l %s" "${target}" | \ ${SFTP} -b - -D ${SFTPSERVER} 2>/dev/null | \ grep -v "^sftp>" > ${RESULTS} if [ $? -ne 0 ]; then fail "$errtag failed" fi if test "x$expected" != "x" ; then if fgrep "$expected" ${RESULTS} >/dev/null 2>&1 ; then : else fail "$expected missing from $errtag results" fi fi if test "x$unexpected" != "x" && \ fgrep "$unexpected" ${RESULTS} >/dev/null 2>&1 ; then fail "$unexpected present in $errtag results" fi rm -f ${RESULTS} } BASE=${OBJ}/glob RESULTS=${OBJ}/results DIR=${BASE}/dir DATA=${DIR}/file GLOB1="${DIR}/g-wild*" GLOB2="${DIR}/g-wildx" QUOTE="${DIR}/g-quote\"" SLASH="${DIR}/g-sl\\ash" ESLASH="${DIR}/g-slash\\" QSLASH="${DIR}/g-qs\\\"" SPACE="${DIR}/g-q space" rm -rf ${BASE} mkdir -p ${DIR} touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}" "${SPACE}" test "x$nobs" = "x" && touch "${QSLASH}" "${ESLASH}" "${SLASH}" # target message expected unexpected sftp_ls "${DIR}/fil*" "file glob" "${DATA}" "" sftp_ls "${BASE}/d*" "dir glob" "`basename ${DATA}`" "" sftp_ls "${DIR}/g-wild\"*\"" "quoted glob" "g-wild*" "g-wildx" sftp_ls "${DIR}/g-wild\*" "escaped glob" "g-wild*" "g-wildx" sftp_ls "${DIR}/g-quote\\\"" "escaped quote" "g-quote\"" "" sftp_ls "\"${DIR}/g-quote\\\"\"" "quoted quote" "g-quote\"" "" sftp_ls "'${DIR}/g-quote\"'" "single-quoted quote" "g-quote\"" "" sftp_ls "${DIR}/g-q\\ space" "escaped space" "g-q space" "" sftp_ls "'${DIR}/g-q space'" "quoted space" "g-q space" "" sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" "" "$nobs" sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" "" "$nobs" sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" "" "$nobs" sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" "" "$nobs" sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" "" "$nobs" sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" "" "$nobs" rm -rf ${BASE} openssh-7.2p2/regress/sftp-perm.sh010064400017500001750000000123561267006270000154040ustar00djmdjm# $OpenBSD: sftp-perm.sh,v 1.2 2013/10/17 22:00:18 djm Exp $ # Placed in the Public Domain. tid="sftp permissions" SERVER_LOG=${OBJ}/sftp-server.log CLIENT_LOG=${OBJ}/sftp.log TEST_SFTP_SERVER=${OBJ}/sftp-server.sh prepare_server() { printf "#!/bin/sh\nexec $SFTPSERVER -el debug3 $* 2>$SERVER_LOG\n" \ > $TEST_SFTP_SERVER chmod a+x $TEST_SFTP_SERVER } run_client() { echo "$@" | ${SFTP} -D ${TEST_SFTP_SERVER} -vvvb - >$CLIENT_LOG 2>&1 } prepare_files() { _prep="$1" rm -f ${COPY} ${COPY}.1 test -d ${COPY}.dd && { rmdir ${COPY}.dd || fatal "rmdir ${COPY}.dd"; } test -z "$_prep" && return sh -c "$_prep" || fail "preparation failed: \"$_prep\"" } postcondition() { _title="$1" _check="$2" test -z "$_check" && return ${TEST_SHELL} -c "$_check" || fail "postcondition check failed: $_title" } ro_test() { _desc=$1 _cmd="$2" _prep="$3" _expect_success_post="$4" _expect_fail_post="$5" verbose "$tid: read-only $_desc" # Plain (no options, mostly to test that _cmd is good) prepare_files "$_prep" prepare_server run_client "$_cmd" || fail "plain $_desc failed" postcondition "$_desc no-readonly" "$_expect_success_post" # Read-only enabled prepare_files "$_prep" prepare_server -R run_client "$_cmd" && fail "read-only $_desc succeeded" postcondition "$_desc readonly" "$_expect_fail_post" } perm_test() { _op=$1 _whitelist_ops=$2 _cmd="$3" _prep="$4" _expect_success_post="$5" _expect_fail_post="$6" verbose "$tid: explicit $_op" # Plain (no options, mostly to test that _cmd is good) prepare_files "$_prep" prepare_server run_client "$_cmd" || fail "plain $_op failed" postcondition "$_op no white/blacklists" "$_expect_success_post" # Whitelist prepare_files "$_prep" prepare_server -p $_op,$_whitelist_ops run_client "$_cmd" || fail "whitelisted $_op failed" postcondition "$_op whitelisted" "$_expect_success_post" # Blacklist prepare_files "$_prep" prepare_server -P $_op run_client "$_cmd" && fail "blacklisted $_op succeeded" postcondition "$_op blacklisted" "$_expect_fail_post" # Whitelist with op missing. prepare_files "$_prep" prepare_server -p $_whitelist_ops run_client "$_cmd" && fail "no whitelist $_op succeeded" postcondition "$_op not in whitelist" "$_expect_fail_post" } ro_test \ "upload" \ "put $DATA $COPY" \ "" \ "cmp $DATA $COPY" \ "test ! -f $COPY" ro_test \ "setstat" \ "chmod 0700 $COPY" \ "touch $COPY; chmod 0400 $COPY" \ "test -x $COPY" \ "test ! -x $COPY" ro_test \ "rm" \ "rm $COPY" \ "touch $COPY" \ "test ! -f $COPY" \ "test -f $COPY" ro_test \ "mkdir" \ "mkdir ${COPY}.dd" \ "" \ "test -d ${COPY}.dd" \ "test ! -d ${COPY}.dd" ro_test \ "rmdir" \ "rmdir ${COPY}.dd" \ "mkdir ${COPY}.dd" \ "test ! -d ${COPY}.dd" \ "test -d ${COPY}.dd" ro_test \ "posix-rename" \ "rename $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1 -a ! -f $COPY" \ "test -f $COPY -a ! -f ${COPY}.1" ro_test \ "oldrename" \ "rename -l $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1 -a ! -f $COPY" \ "test -f $COPY -a ! -f ${COPY}.1" ro_test \ "symlink" \ "ln -s $COPY ${COPY}.1" \ "touch $COPY" \ "test -h ${COPY}.1" \ "test ! -h ${COPY}.1" ro_test \ "hardlink" \ "ln $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1" \ "test ! -f ${COPY}.1" # Test explicit permissions perm_test \ "open" \ "realpath,stat,lstat,read,close" \ "get $DATA $COPY" \ "" \ "cmp $DATA $COPY" \ "! cmp $DATA $COPY 2>/dev/null" perm_test \ "read" \ "realpath,stat,lstat,open,close" \ "get $DATA $COPY" \ "" \ "cmp $DATA $COPY" \ "! cmp $DATA $COPY 2>/dev/null" perm_test \ "write" \ "realpath,stat,lstat,open,close" \ "put $DATA $COPY" \ "" \ "cmp $DATA $COPY" \ "! cmp $DATA $COPY 2>/dev/null" perm_test \ "lstat" \ "realpath,stat,open,read,close" \ "get $DATA $COPY" \ "" \ "cmp $DATA $COPY" \ "! cmp $DATA $COPY 2>/dev/null" perm_test \ "opendir" \ "realpath,readdir,stat,lstat" \ "ls -ln $OBJ" perm_test \ "readdir" \ "realpath,opendir,stat,lstat" \ "ls -ln $OBJ" perm_test \ "setstat" \ "realpath,stat,lstat" \ "chmod 0700 $COPY" \ "touch $COPY; chmod 0400 $COPY" \ "test -x $COPY" \ "test ! -x $COPY" perm_test \ "remove" \ "realpath,stat,lstat" \ "rm $COPY" \ "touch $COPY" \ "test ! -f $COPY" \ "test -f $COPY" perm_test \ "mkdir" \ "realpath,stat,lstat" \ "mkdir ${COPY}.dd" \ "" \ "test -d ${COPY}.dd" \ "test ! -d ${COPY}.dd" perm_test \ "rmdir" \ "realpath,stat,lstat" \ "rmdir ${COPY}.dd" \ "mkdir ${COPY}.dd" \ "test ! -d ${COPY}.dd" \ "test -d ${COPY}.dd" perm_test \ "posix-rename" \ "realpath,stat,lstat" \ "rename $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1 -a ! -f $COPY" \ "test -f $COPY -a ! -f ${COPY}.1" perm_test \ "rename" \ "realpath,stat,lstat" \ "rename -l $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1 -a ! -f $COPY" \ "test -f $COPY -a ! -f ${COPY}.1" perm_test \ "symlink" \ "realpath,stat,lstat" \ "ln -s $COPY ${COPY}.1" \ "touch $COPY" \ "test -h ${COPY}.1" \ "test ! -h ${COPY}.1" perm_test \ "hardlink" \ "realpath,stat,lstat" \ "ln $COPY ${COPY}.1" \ "touch $COPY" \ "test -f ${COPY}.1" \ "test ! -f ${COPY}.1" perm_test \ "statvfs" \ "realpath,stat,lstat" \ "df /" # XXX need good tests for: # fstat # fsetstat # realpath # stat # readlink # fstatvfs rm -rf ${COPY} ${COPY}.1 ${COPY}.dd openssh-7.2p2/regress/sftp.sh010064400017500001750000000013661267006270000144420ustar00djmdjm# $OpenBSD: sftp.sh,v 1.5 2013/05/17 10:28:11 dtucker Exp $ # Placed in the Public Domain. tid="basic sftp put/get" SFTPCMDFILE=${OBJ}/batch cat >$SFTPCMDFILE < /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "sftp failed with $r" else cmp $DATA ${COPY}.1 || fail "corrupted copy after get" cmp $DATA ${COPY}.2 || fail "corrupted copy after put" fi done done rm -f ${COPY}.1 ${COPY}.2 rm -f $SFTPCMDFILE openssh-7.2p2/regress/ssh-com-client.sh010064400017500001750000000060271267006270000163120ustar00djmdjm# $OpenBSD: ssh-com-client.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="connect with ssh.com client" #TEST_COMBASE=/path/to/ssh/com/binaries if [ "X${TEST_COMBASE}" = "X" ]; then fatal '$TEST_COMBASE is not set' fi VERSIONS=" 2.1.0 2.2.0 2.3.0 2.3.1 2.4.0 3.0.0 3.1.0 3.2.0 3.2.2 3.2.3 3.2.5 3.2.9 3.2.9.1 3.3.0" # 2.0.10 2.0.12 2.0.13 don't like the test setup # setup authorized keys SRC=`dirname ${SCRIPT}` cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com chmod 600 ${OBJ}/id.com ${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh chmod 600 ${OBJ}/id.openssh ${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER ${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub echo IdKey ${OBJ}/id.com > ${OBJ}/id.list # we need a DSA host key t=dsa rm -f ${OBJ}/$t ${OBJ}/$t.pub ${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t $SUDO cp $OBJ/$t $OBJ/host.$t echo HostKey $OBJ/host.$t >> $OBJ/sshd_config # add hostkeys to known hosts mkdir -p ${OBJ}/${USER}/hostkeys HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1 ${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub ${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub cat > ${OBJ}/ssh2_config << EOF *: QuietMode yes StrictHostKeyChecking yes Port ${PORT} User ${USER} Host 127.0.0.1 IdentityFile ${OBJ}/id.list RandomSeedFile ${OBJ}/random_seed UserConfigDirectory ${OBJ}/%U AuthenticationSuccessMsg no BatchMode yes ForwardX11 no EOF # we need a real server (no ProxyConnect option) start_sshd # go for it for v in ${VERSIONS}; do ssh2=${TEST_COMBASE}/${v}/ssh2 if [ ! -x ${ssh2} ]; then continue fi verbose "ssh2 ${v}" key=ssh-dss skipcat=0 case $v in 2.1.*|2.3.0) skipcat=1 ;; 3.0.*) key=ssh-rsa ;; esac cp ${HK}.$key.pub ${HK}.pub # check exit status ${ssh2} -q -F ${OBJ}/ssh2_config somehost exit 42 r=$? if [ $r -ne 42 ]; then fail "ssh2 ${v} exit code test failed (got $r, expected 42)" fi # data transfer rm -f ${COPY} ${ssh2} -F ${OBJ}/ssh2_config somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh2 ${v} cat test (receive) failed" fi cmp ${DATA} ${COPY} || fail "ssh2 ${v} cat test (receive) data mismatch" # data transfer, again if [ $skipcat -eq 0 ]; then rm -f ${COPY} cat ${DATA} | \ ${ssh2} -F ${OBJ}/ssh2_config host "cat > ${COPY}" if [ $? -ne 0 ]; then fail "ssh2 ${v} cat test (send) failed" fi cmp ${DATA} ${COPY} || \ fail "ssh2 ${v} cat test (send) data mismatch" fi # no stderr after eof rm -f ${COPY} ${ssh2} -F ${OBJ}/ssh2_config somehost \ exec sh -c \'"exec > /dev/null; sleep 1; echo bla 1>&2; exit 0"\' \ 2> /dev/null if [ $? -ne 0 ]; then fail "ssh2 ${v} stderr test failed" fi done rm -rf ${OBJ}/${USER} for i in ssh2_config random_seed dsa.pub dsa host.dsa \ id.list id.com id.com.pub id.openssh; do rm -f ${OBJ}/$i done openssh-7.2p2/regress/ssh-com-keygen.sh010064400017500001750000000026051267006270000163140ustar00djmdjm# $OpenBSD: ssh-com-keygen.sh,v 1.4 2004/02/24 17:06:52 markus Exp $ # Placed in the Public Domain. tid="ssh.com key import" #TEST_COMBASE=/path/to/ssh/com/binaries if [ "X${TEST_COMBASE}" = "X" ]; then fatal '$TEST_COMBASE is not set' fi VERSIONS=" 2.0.10 2.0.12 2.0.13 2.1.0 2.2.0 2.3.0 2.3.1 2.4.0 3.0.0 3.1.0 3.2.0 3.2.2 3.2.3 3.2.5 3.2.9 3.2.9.1 3.3.0" COMPRV=${OBJ}/comkey COMPUB=${COMPRV}.pub OPENSSHPRV=${OBJ}/opensshkey OPENSSHPUB=${OPENSSHPRV}.pub # go for it for v in ${VERSIONS}; do keygen=${TEST_COMBASE}/${v}/ssh-keygen2 if [ ! -x ${keygen} ]; then continue fi types="dss" case $v in 2.3.1|3.*) types="$types rsa" ;; esac for t in $types; do verbose "ssh-keygen $v/$t" rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB ${keygen} -q -P -t $t ${COMPRV} > /dev/null 2>&1 if [ $? -ne 0 ]; then fail "${keygen} -t $t failed" continue fi ${SSHKEYGEN} -if ${COMPUB} > ${OPENSSHPUB} if [ $? -ne 0 ]; then fail "import public key ($v/$t) failed" continue fi ${SSHKEYGEN} -if ${COMPRV} > ${OPENSSHPRV} if [ $? -ne 0 ]; then fail "import private key ($v/$t) failed" continue fi chmod 600 ${OPENSSHPRV} ${SSHKEYGEN} -yf ${OPENSSHPRV} |\ diff - ${OPENSSHPUB} if [ $? -ne 0 ]; then fail "public keys ($v/$t) differ" fi done done rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB openssh-7.2p2/regress/ssh-com-sftp.sh010064400017500001750000000023061267006270000160040ustar00djmdjm# $OpenBSD: ssh-com-sftp.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="basic sftp put/get with ssh.com server" SFTPCMDFILE=${OBJ}/batch cat >$SFTPCMDFILE < /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "sftp failed with $r" else cmp $DATA ${COPY}.1 || fail "corrupted copy after get" cmp $DATA ${COPY}.2 || fail "corrupted copy after put" fi done done done rm -f ${COPY}.1 ${COPY}.2 rm -f $SFTPCMDFILE openssh-7.2p2/regress/ssh-com.sh010064400017500001750000000053541267006270000150400ustar00djmdjm# $OpenBSD: ssh-com.sh,v 1.9 2015/05/08 07:29:00 djm Exp $ # Placed in the Public Domain. tid="connect to ssh.com server" #TEST_COMBASE=/path/to/ssh/com/binaries if [ "X${TEST_COMBASE}" = "X" ]; then fatal '$TEST_COMBASE is not set' fi VERSIONS=" 2.0.12 2.0.13 2.1.0 2.2.0 2.3.0 2.4.0 3.0.0 3.1.0 3.2.0 3.2.2 3.2.3 3.2.5 3.2.9 3.2.9.1 3.3.0" # 2.0.10 does not support UserConfigDirectory # 2.3.1 requires a config in $HOME/.ssh2 SRC=`dirname ${SCRIPT}` # ssh.com cat << EOF > $OBJ/sshd2_config #*: # Port and ListenAddress are not used. QuietMode yes Port 4343 ListenAddress 127.0.0.1 UserConfigDirectory ${OBJ}/%U Ciphers AnyCipher PubKeyAuthentication yes #AllowedAuthentications publickey AuthorizationFile authorization HostKeyFile ${SRC}/dsa_ssh2.prv PublicHostKeyFile ${SRC}/dsa_ssh2.pub RandomSeedFile ${OBJ}/random_seed MaxConnections 0 PermitRootLogin yes VerboseMode no CheckMail no Ssh1Compatibility no EOF # create client config sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ < $OBJ/ssh_config > $OBJ/ssh_config_com # we need a DSA key for rm -f ${OBJ}/dsa ${OBJ}/dsa.pub ${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa # setup userdir, try rsa first mkdir -p ${OBJ}/${USER} cp /dev/null ${OBJ}/${USER}/authorization for t in rsa dsa; do ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com echo Key $t.com >> ${OBJ}/${USER}/authorization echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com done # convert and append DSA hostkey ( printf 'ssh2-localhost-with-alias,127.0.0.1,::1 ' ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub ) >> $OBJ/known_hosts # go for it for v in ${VERSIONS}; do sshd2=${TEST_COMBASE}/${v}/sshd2 if [ ! -x ${sshd2} ]; then continue fi trace "sshd2 ${v}" PROXY="proxycommand ${sshd2} -qif ${OBJ}/sshd2_config 2> /dev/null" ${SSH} -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 if [ $? -ne 0 ]; then fail "ssh connect to sshd2 ${v} failed" fi ciphers="3des-cbc blowfish-cbc arcfour" macs="hmac-md5" case $v in 2.4.*) ciphers="$ciphers cast128-cbc" macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" ;; 3.*) ciphers="$ciphers aes128-cbc cast128-cbc" macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" ;; esac #ciphers="3des-cbc" for m in $macs; do for c in $ciphers; do trace "sshd2 ${v} cipher $c mac $m" verbose "test ${tid}: sshd2 ${v} cipher $c mac $m" ${SSH} -c $c -m $m -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 if [ $? -ne 0 ]; then fail "ssh connect to sshd2 ${v} with $c/$m failed" fi done done done rm -rf ${OBJ}/${USER} for i in sshd_config_proxy ssh_config_proxy random_seed \ sshd2_config dsa.pub dsa ssh_config_com; do rm -f ${OBJ}/$i done openssh-7.2p2/regress/ssh2putty.sh010075500017500001750000000012651267006270000154540ustar00djmdjm#!/bin/sh # $OpenBSD: ssh2putty.sh,v 1.3 2015/05/08 07:26:13 djm Exp $ if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then echo "Usage: ssh2putty hostname port ssh-private-key" exit 1 fi HOST=$1 PORT=$2 KEYFILE=$3 # XXX - support DSA keys too if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then : else echo "Unsupported private key format" exit 1 fi public_exponent=` openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent | sed 's/.*(//;s/).*//' ` test $? -ne 0 && exit 1 modulus=` openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= | sed 's/^Modulus=/0x/' | tr A-Z a-z ` test $? -ne 0 && exit 1 echo "rsa2@$PORT:$HOST $public_exponent,$modulus" openssh-7.2p2/regress/sshd-log-wrapper.sh010064400017500001750000000004351267006270000166600ustar00djmdjm#!/bin/sh # $OpenBSD: sshd-log-wrapper.sh,v 1.3 2013/04/07 02:16:03 dtucker Exp $ # Placed in the Public Domain. # # simple wrapper for sshd proxy mode to catch stderr output # sh sshd-log-wrapper.sh /path/to/logfile /path/to/sshd [args...] log=$1 shift exec "$@" -E$log openssh-7.2p2/regress/stderr-after-eof.sh010064400017500001750000000011421267006270000166270ustar00djmdjm# $OpenBSD: stderr-after-eof.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ # Placed in the Public Domain. tid="stderr data after eof" # setup data rm -f ${DATA} ${COPY} cp /dev/null ${DATA} for i in 1 2 3 4 5 6; do (date;echo $i) | md5 >> ${DATA} done ${SSH} -2 -F $OBJ/ssh_proxy otherhost \ exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \ 2> ${COPY} r=$? if [ $r -ne 0 ]; then fail "ssh failed with exit code $r" fi egrep 'Disconnecting: Received extended_data after EOF' ${COPY} && fail "ext data received after eof" cmp ${DATA} ${COPY} || fail "stderr corrupt" rm -f ${DATA} ${COPY} openssh-7.2p2/regress/stderr-data.sh010064400017500001750000000013661267006270000157000ustar00djmdjm# $OpenBSD: stderr-data.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="stderr data transfer" for n in '' -n; do for p in ${SSH_PROTOCOLS}; do verbose "test $tid: proto $p ($n)" ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ 2> ${COPY} r=$? if [ $r -ne 0 ]; then fail "ssh failed with exit code $r" fi cmp ${DATA} ${COPY} || fail "stderr corrupt" rm -f ${COPY} ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ exec sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ > /dev/null 2> ${COPY} r=$? if [ $r -ne 0 ]; then fail "ssh failed with exit code $r" fi cmp ${DATA} ${COPY} || fail "stderr corrupt" rm -f ${COPY} done done openssh-7.2p2/regress/t11.ok010064400017500001750000000000631267006270000140630ustar00djmdjmSHA256:4w1rnrek3klTJOTVhwuCIFd5k+pq9Bfo5KTxxb8BqbY openssh-7.2p2/regress/t4.ok010064400017500001750000000000641267006270000140060ustar00djmdjmMD5:3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 openssh-7.2p2/regress/t5.ok010064400017500001750000000001021267006270000140000ustar00djmdjmxokes-lylis-byleh-zebib-kalus-bihas-tevah-haroz-suhar-foved-noxex openssh-7.2p2/regress/test-exec.sh010064400017500001750000000277721267006270000154000ustar00djmdjm# $OpenBSD: test-exec.sh,v 1.51 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. #SUDO=sudo # Unbreak GNU head(1) _POSIX2_VERSION=199209 export _POSIX2_VERSION case `uname -s 2>/dev/null` in OSF1*) BIN_SH=xpg4 export BIN_SH ;; CYGWIN_NT-5.0) os=cygwin TEST_SSH_IPV6=no ;; CYGWIN*) os=cygwin ;; esac if [ ! -z "$TEST_SSH_PORT" ]; then PORT="$TEST_SSH_PORT" else PORT=4242 fi if [ -x /usr/ucb/whoami ]; then USER=`/usr/ucb/whoami` elif whoami >/dev/null 2>&1; then USER=`whoami` elif logname >/dev/null 2>&1; then USER=`logname` else USER=`id -un` fi OBJ=$1 if [ "x$OBJ" = "x" ]; then echo '$OBJ not defined' exit 2 fi if [ ! -d $OBJ ]; then echo "not a directory: $OBJ" exit 2 fi SCRIPT=$2 if [ "x$SCRIPT" = "x" ]; then echo '$SCRIPT not defined' exit 2 fi if [ ! -f $SCRIPT ]; then echo "not a file: $SCRIPT" exit 2 fi if $TEST_SHELL -n $SCRIPT; then true else echo "syntax error in $SCRIPT" exit 2 fi unset SSH_AUTH_SOCK SRC=`dirname ${SCRIPT}` # defaults SSH=ssh SSHD=sshd SSHAGENT=ssh-agent SSHADD=ssh-add SSHKEYGEN=ssh-keygen SSHKEYSCAN=ssh-keyscan SFTP=sftp SFTPSERVER=/usr/libexec/openssh/sftp-server SCP=scp # Interop testing PLINK=plink PUTTYGEN=puttygen CONCH=conch if [ "x$TEST_SSH_SSH" != "x" ]; then SSH="${TEST_SSH_SSH}" fi if [ "x$TEST_SSH_SSHD" != "x" ]; then SSHD="${TEST_SSH_SSHD}" fi if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then SSHAGENT="${TEST_SSH_SSHAGENT}" fi if [ "x$TEST_SSH_SSHADD" != "x" ]; then SSHADD="${TEST_SSH_SSHADD}" fi if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then SSHKEYGEN="${TEST_SSH_SSHKEYGEN}" fi if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}" fi if [ "x$TEST_SSH_SFTP" != "x" ]; then SFTP="${TEST_SSH_SFTP}" fi if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then SFTPSERVER="${TEST_SSH_SFTPSERVER}" fi if [ "x$TEST_SSH_SCP" != "x" ]; then SCP="${TEST_SSH_SCP}" fi if [ "x$TEST_SSH_PLINK" != "x" ]; then # Find real binary, if it exists case "${TEST_SSH_PLINK}" in /*) PLINK="${TEST_SSH_PLINK}" ;; *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;; esac fi if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then # Find real binary, if it exists case "${TEST_SSH_PUTTYGEN}" in /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;; *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;; esac fi if [ "x$TEST_SSH_CONCH" != "x" ]; then # Find real binary, if it exists case "${TEST_SSH_CONCH}" in /*) CONCH="${TEST_SSH_CONCH}" ;; *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;; esac fi SSH_PROTOCOLS=`$SSH -Q protocol-version` if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}" fi # Path to sshd must be absolute for rexec case "$SSHD" in /*) ;; *) SSHD=`which $SSHD` ;; esac case "$SSHAGENT" in /*) ;; *) SSHAGENT=`which $SSHAGENT` ;; esac # Record the actual binaries used. SSH_BIN=${SSH} SSHD_BIN=${SSHD} SSHAGENT_BIN=${SSHAGENT} SSHADD_BIN=${SSHADD} SSHKEYGEN_BIN=${SSHKEYGEN} SSHKEYSCAN_BIN=${SSHKEYSCAN} SFTP_BIN=${SFTP} SFTPSERVER_BIN=${SFTPSERVER} SCP_BIN=${SCP} if [ "x$USE_VALGRIND" != "x" ]; then mkdir -p $OBJ/valgrind-out VG_TEST=`basename $SCRIPT .sh` # Some tests are difficult to fix. case "$VG_TEST" in connect-privsep|reexec) VG_SKIP=1 ;; esac if [ x"$VG_SKIP" = "x" ]; then VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*" VG_LOG="$OBJ/valgrind-out/${VG_TEST}." VG_OPTS="--track-origins=yes --leak-check=full" VG_OPTS="$VG_OPTS --trace-children=yes" VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}" VG_PATH="valgrind" if [ "x$VALGRIND_PATH" != "x" ]; then VG_PATH="$VALGRIND_PATH" fi VG="$VG_PATH $VG_OPTS" SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH" SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD" SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT" SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD" SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN" SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN" SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}" SCP="$VG --log-file=${VG_LOG}scp.%p $SCP" cat > $OBJ/valgrind-sftp-server.sh << EOF #!/bin/sh exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@" EOF chmod a+rx $OBJ/valgrind-sftp-server.sh SFTPSERVER="$OBJ/valgrind-sftp-server.sh" fi fi # Logfiles. # SSH_LOGFILE should be the debug output of ssh(1) only # SSHD_LOGFILE should be the debug output of sshd(8) only # REGRESS_LOGFILE is the output of the test itself stdout and stderr if [ "x$TEST_SSH_LOGFILE" = "x" ]; then TEST_SSH_LOGFILE=$OBJ/ssh.log fi if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then TEST_SSHD_LOGFILE=$OBJ/sshd.log fi if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then TEST_REGRESS_LOGFILE=$OBJ/regress.log fi # truncate logfiles >$TEST_SSH_LOGFILE >$TEST_SSHD_LOGFILE >$TEST_REGRESS_LOGFILE # Create wrapper ssh with logging. We can't just specify "SSH=ssh -E..." # because sftp and scp don't handle spaces in arguments. SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh echo "#!/bin/sh" > $SSHLOGWRAP echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP chmod a+rx $OBJ/ssh-log-wrapper.sh SSH="$SSHLOGWRAP" # Some test data. We make a copy because some tests will overwrite it. # The tests may assume that $DATA exists and is writable and $COPY does # not exist. Tests requiring larger data files can call increase_datafile_size # [kbytes] to ensure the file is at least that large. DATANAME=data DATA=$OBJ/${DATANAME} cat ${SSHAGENT_BIN} >${DATA} chmod u+w ${DATA} COPY=$OBJ/copy rm -f ${COPY} increase_datafile_size() { while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do cat ${SSHAGENT_BIN} >>${DATA} done } # these should be used in tests export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP # Portable specific functions have_prog() { saved_IFS="$IFS" IFS=":" for i in $PATH do if [ -x $i/$1 ]; then IFS="$saved_IFS" return 0 fi done IFS="$saved_IFS" return 1 } jot() { awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }" } # Check whether preprocessor symbols are defined in config.h. config_defined () { str=$1 while test "x$2" != "x" ; do str="$str|$2" shift done egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1 } md5 () { if have_prog md5sum; then md5sum elif have_prog openssl; then openssl md5 elif have_prog cksum; then cksum elif have_prog sum; then sum else wc -c fi } # End of portable specific functions # helper cleanup () { if [ "x$SSH_PID" != "x" ]; then if [ $SSH_PID -lt 2 ]; then echo bad pid for ssh: $SSH_PID else kill $SSH_PID fi fi if [ -f $PIDFILE ]; then pid=`$SUDO cat $PIDFILE` if [ "X$pid" = "X" ]; then echo no sshd running else if [ $pid -lt 2 ]; then echo bad pid for sshd: $pid else $SUDO kill $pid trace "wait for sshd to exit" i=0; while [ -f $PIDFILE -a $i -lt 5 ]; do i=`expr $i + 1` sleep $i done test -f $PIDFILE && \ fatal "sshd didn't exit port $PORT pid $pid" fi fi fi } start_debug_log () { echo "trace: $@" >$TEST_REGRESS_LOGFILE echo "trace: $@" >$TEST_SSH_LOGFILE echo "trace: $@" >$TEST_SSHD_LOGFILE } save_debug_log () { echo $@ >>$TEST_REGRESS_LOGFILE echo $@ >>$TEST_SSH_LOGFILE echo $@ >>$TEST_SSHD_LOGFILE (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log } trace () { start_debug_log $@ if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then echo "$@" fi } verbose () { start_debug_log $@ if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then echo "$@" fi } warn () { echo "WARNING: $@" >>$TEST_SSH_LOGFILE echo "WARNING: $@" } fail () { save_debug_log "FAIL: $@" RESULT=1 echo "$@" } fatal () { save_debug_log "FATAL: $@" printf "FATAL: " fail "$@" cleanup exit $RESULT } ssh_version () { echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null } RESULT=0 PIDFILE=$OBJ/pidfile trap fatal 3 2 if ssh_version 1; then PROTO="2,1" else PROTO="2" fi # create server config cat << EOF > $OBJ/sshd_config StrictModes no Port $PORT Protocol $PROTO AddressFamily inet ListenAddress 127.0.0.1 #ListenAddress ::1 PidFile $PIDFILE AuthorizedKeysFile $OBJ/authorized_keys_%u LogLevel DEBUG3 AcceptEnv _XXX_TEST_* AcceptEnv _XXX_TEST Subsystem sftp $SFTPSERVER EOF if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS" echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config fi # server config for proxy connects cp $OBJ/sshd_config $OBJ/sshd_proxy # allow group-writable directories in proxy-mode echo 'StrictModes no' >> $OBJ/sshd_proxy # create client config cat << EOF > $OBJ/ssh_config Host * Protocol $PROTO Hostname 127.0.0.1 HostKeyAlias localhost-with-alias Port $PORT User $USER GlobalKnownHostsFile $OBJ/known_hosts UserKnownHostsFile $OBJ/known_hosts RSAAuthentication yes PubkeyAuthentication yes ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication no RhostsRSAAuthentication no BatchMode yes StrictHostKeyChecking yes LogLevel DEBUG3 EOF if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS" echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config fi rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER if ssh_version 1; then SSH_KEYTYPES="rsa rsa1" else SSH_KEYTYPES="rsa ed25519" fi trace "generate keys" for t in ${SSH_KEYTYPES}; do # generate user key if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then rm -f $OBJ/$t ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ fail "ssh-keygen for $t failed" fi # known hosts file for client ( printf 'localhost-with-alias,127.0.0.1,::1 ' cat $OBJ/$t.pub ) >> $OBJ/known_hosts # setup authorized keys cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER echo IdentityFile $OBJ/$t >> $OBJ/ssh_config # use key as host key, too $SUDO cp $OBJ/$t $OBJ/host.$t echo HostKey $OBJ/host.$t >> $OBJ/sshd_config # don't use SUDO for proxy connect echo HostKey $OBJ/$t >> $OBJ/sshd_proxy done chmod 644 $OBJ/authorized_keys_$USER # Activate Twisted Conch tests if the binary is present REGRESS_INTEROP_CONCH=no if test -x "$CONCH" ; then REGRESS_INTEROP_CONCH=yes fi # If PuTTY is present and we are running a PuTTY test, prepare keys and # configuration REGRESS_INTEROP_PUTTY=no if test -x "$PUTTYGEN" -a -x "$PLINK" ; then REGRESS_INTEROP_PUTTY=yes fi case "$SCRIPT" in *putty*) ;; *) REGRESS_INTEROP_PUTTY=no ;; esac if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then mkdir -p ${OBJ}/.putty # Add a PuTTY key to authorized_keys rm -f ${OBJ}/putty.rsa2 puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null puttygen -O public-openssh ${OBJ}/putty.rsa2 \ >> $OBJ/authorized_keys_$USER # Convert rsa2 host key to PuTTY format ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \ ${OBJ}/.putty/sshhostkeys ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \ ${OBJ}/.putty/sshhostkeys # Setup proxied session mkdir -p ${OBJ}/.putty/sessions rm -f ${OBJ}/.putty/sessions/localhost_proxy echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy REGRESS_INTEROP_PUTTY=yes fi # create a proxy version of the client config ( cat $OBJ/ssh_config echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy ) > $OBJ/ssh_proxy # check proxy config ${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken" start_sshd () { # start sshd $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE trace "wait for sshd" i=0; while [ ! -f $PIDFILE -a $i -lt 10 ]; do i=`expr $i + 1` sleep $i done test -f $PIDFILE || fatal "no sshd running on port $PORT" } # source test body . $SCRIPT # kill sshd cleanup if [ $RESULT -eq 0 ]; then verbose ok $tid else echo failed $tid fi exit $RESULT openssh-7.2p2/regress/transfer.sh010064400017500001750000000012501267006270000153020ustar00djmdjm# $OpenBSD: transfer.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="transfer data" for p in ${SSH_PROTOCOLS}; do verbose "$tid: proto $p" rm -f ${COPY} ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp ${DATA} ${COPY} || fail "corrupted copy" for s in 10 100 1k 32k 64k 128k 256k; do trace "proto $p dd-size ${s}" rm -f ${COPY} dd if=$DATA obs=${s} 2> /dev/null | \ ${SSH} -q -$p -F $OBJ/ssh_proxy somehost "cat > ${COPY}" if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi cmp $DATA ${COPY} || fail "corrupted copy" done done rm -f ${COPY} openssh-7.2p2/regress/try-ciphers.sh010064400017500001750000000017711267006270000157370ustar00djmdjm# $OpenBSD: try-ciphers.sh,v 1.25 2015/03/24 20:22:17 markus Exp $ # Placed in the Public Domain. tid="try ciphers" cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak for c in `${SSH} -Q cipher`; do n=0 for m in `${SSH} -Q mac`; do trace "proto 2 cipher $c mac $m" verbose "test $tid: proto 2 cipher $c mac $m" cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "Ciphers=$c" >> $OBJ/sshd_proxy echo "MACs=$m" >> $OBJ/sshd_proxy ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true if [ $? -ne 0 ]; then fail "ssh -2 failed with mac $m cipher $c" fi # No point trying all MACs for AEAD ciphers since they # are ignored. if ${SSH} -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then break fi n=`expr $n + 1` done done if ssh_version 1; then ciphers="3des blowfish" else ciphers="" fi for c in $ciphers; do trace "proto 1 cipher $c" verbose "test $tid: proto 1 cipher $c" ${SSH} -F $OBJ/ssh_proxy -1 -c $c somehost true if [ $? -ne 0 ]; then fail "ssh -1 failed with cipher $c" fi done openssh-7.2p2/regress/unittests004075500017500001750000000000001267006270000151125ustar00djmdjmopenssh-7.2p2/regress/unittests/Makefile010064400017500001750000000002411267006270000166230ustar00djmdjm# $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $ REGRESS_FAIL_EARLY= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys .include openssh-7.2p2/regress/unittests/Makefile.inc010064400017500001750000000027731267006270000174070ustar00djmdjm# $OpenBSD: Makefile.inc,v 1.6 2015/07/01 23:11:18 djm Exp $ .include .include # enable warnings WARNINGS=Yes DEBUG=-g CFLAGS+= -fstack-protector-all CDIAGFLAGS= -Wall CDIAGFLAGS+= -Wextra CDIAGFLAGS+= -Werror CDIAGFLAGS+= -Wchar-subscripts CDIAGFLAGS+= -Wcomment CDIAGFLAGS+= -Wformat CDIAGFLAGS+= -Wformat-security CDIAGFLAGS+= -Wimplicit CDIAGFLAGS+= -Winline CDIAGFLAGS+= -Wmissing-declarations CDIAGFLAGS+= -Wmissing-prototypes CDIAGFLAGS+= -Wparentheses CDIAGFLAGS+= -Wpointer-arith CDIAGFLAGS+= -Wreturn-type CDIAGFLAGS+= -Wshadow CDIAGFLAGS+= -Wsign-compare CDIAGFLAGS+= -Wstrict-aliasing CDIAGFLAGS+= -Wstrict-prototypes CDIAGFLAGS+= -Wswitch CDIAGFLAGS+= -Wtrigraphs CDIAGFLAGS+= -Wuninitialized CDIAGFLAGS+= -Wunused .if ${COMPILER_VERSION} == "gcc4" CDIAGFLAGS+= -Wpointer-sign CDIAGFLAGS+= -Wold-style-definition .endif SSHREL=../../../../../usr.bin/ssh CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL} .if exists(${.CURDIR}/../test_helper/${__objdir}) LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a .else LDADD+=-L${.CURDIR}/../test_helper -ltest_helper DPADD+=${.CURDIR}/../test_helper/libtest_helper.a .endif .if exists(${.CURDIR}/${SSHREL}/lib/${__objdir}) LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a .else LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a .endif LDADD+= -lcrypto DPADD+= ${LIBCRYPTO} openssh-7.2p2/regress/unittests/bitmap004075500017500001750000000000001267006270000163665ustar00djmdjmopenssh-7.2p2/regress/unittests/bitmap/Makefile010064400017500001750000000003711267006270000201030ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $ TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" PROG=test_bitmap SRCS=tests.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include openssh-7.2p2/regress/unittests/bitmap/tests.c010064400017500001750000000057701267006270000177610ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */ /* * Regress test for bitmap.h bitmap API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "../test_helper/test_helper.h" #include "bitmap.h" #define NTESTS 131 void tests(void) { struct bitmap *b; BIGNUM *bn; size_t len; int i, j, k, n; u_char bbuf[1024], bnbuf[1024]; int r; TEST_START("bitmap_new"); b = bitmap_new(); ASSERT_PTR_NE(b, NULL); bn = BN_new(); ASSERT_PTR_NE(bn, NULL); TEST_DONE(); TEST_START("bitmap_set_bit / bitmap_test_bit"); for (i = -1; i < NTESTS; i++) { for (j = -1; j < NTESTS; j++) { for (k = -1; k < NTESTS; k++) { bitmap_zero(b); BN_clear(bn); test_subtest_info("set %d/%d/%d", i, j, k); /* Set bits */ if (i >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, i), 0); ASSERT_INT_EQ(BN_set_bit(bn, i), 1); } if (j >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, j), 0); ASSERT_INT_EQ(BN_set_bit(bn, j), 1); } if (k >= 0) { ASSERT_INT_EQ(bitmap_set_bit(b, k), 0); ASSERT_INT_EQ(BN_set_bit(bn, k), 1); } /* Check perfect match between bitmap and bn */ test_subtest_info("match %d/%d/%d", i, j, k); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } /* Test length calculations */ test_subtest_info("length %d/%d/%d", i, j, k); ASSERT_INT_EQ(BN_num_bits(bn), (int)bitmap_nbits(b)); ASSERT_INT_EQ(BN_num_bytes(bn), (int)bitmap_nbytes(b)); /* Test serialisation */ test_subtest_info("serialise %d/%d/%d", i, j, k); len = bitmap_nbytes(b); memset(bbuf, 0xfc, sizeof(bbuf)); ASSERT_INT_EQ(bitmap_to_string(b, bbuf, sizeof(bbuf)), 0); for (n = len; n < (int)sizeof(bbuf); n++) ASSERT_U8_EQ(bbuf[n], 0xfc); r = BN_bn2bin(bn, bnbuf); ASSERT_INT_GE(r, 0); ASSERT_INT_EQ(r, (int)len); ASSERT_MEM_EQ(bbuf, bnbuf, len); /* Test deserialisation */ test_subtest_info("deserialise %d/%d/%d", i, j, k); bitmap_zero(b); ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, len), 0); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } /* Test clearing bits */ test_subtest_info("clear %d/%d/%d", i, j, k); for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); ASSERT_INT_EQ(BN_set_bit(bn, n), 1); } if (i >= 0) { bitmap_clear_bit(b, i); BN_clear_bit(bn, i); } if (j >= 0) { bitmap_clear_bit(b, j); BN_clear_bit(bn, j); } if (k >= 0) { bitmap_clear_bit(b, k); BN_clear_bit(bn, k); } for (n = 0; n < NTESTS; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } } } } bitmap_free(b); BN_free(bn); TEST_DONE(); } openssh-7.2p2/regress/unittests/hostkeys004075500017500001750000000000001267006270000167635ustar00djmdjmopenssh-7.2p2/regress/unittests/hostkeys/Makefile010064400017500001750000000004411267006270000204760ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $ TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" PROG=test_hostkeys SRCS=tests.c test_iterate.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata .include openssh-7.2p2/regress/unittests/hostkeys/mktestdata.sh010064400017500001750000000053651267006270000215450ustar00djmdjm#!/bin/sh # $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $ set -ex cd testdata rm -f rsa1* rsa* dsa* ecdsa* ed25519* rm -f known_hosts* gen_all() { _n=$1 _ecdsa_bits=256 test "x$_n" = "x1" && _ecdsa_bits=384 test "x$_n" = "x2" && _ecdsa_bits=521 ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n # Don't need private keys rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n } hentries() { _preamble=$1 _kspec=$2 for k in `ls -1 $_kspec | sort` ; do printf "$_preamble " cat $k done echo } gen_all 1 gen_all 2 gen_all 3 gen_all 4 gen_all 5 gen_all 6 # A section of known_hosts with hashed hostnames. ( hentries "sisyphus.example.com" "*_5.pub" hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub" ) > known_hosts_hash_frag ssh-keygen -Hf known_hosts_hash_frag rm -f known_hosts_hash_frag.old # Populated known_hosts, including comments, hashed names and invalid lines ( echo "# Plain host keys, plain host names" hentries "sisyphus.example.com" "*_1.pub" echo "# Plain host keys, hostnames + addresses" hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub" echo "# Some hosts with wildcard names / IPs" hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub" echo "# Hashed hostname and address entries" cat known_hosts_hash_frag rm -f known_hosts_hash_frag echo echo "# Revoked and CA keys" printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub printf "@cert-authority *.example.com " ; cat dsa_4.pub printf "\n" echo "# Some invalid lines" # Invalid marker printf "@what sisyphus.example.com " ; cat rsa1_1.pub # Key missing echo "sisyphus.example.com " # Key blob missing echo "prometheus.example.com ssh-ed25519 " # Key blob truncated echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" # RSA1 key truncated after key bits echo "prometheus.example.com 1024 " # RSA1 key truncated after exponent echo "sisyphus.example.com 1024 65535 " # RSA1 key incorrect key bits printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub # Invalid type echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" # Type mismatch with blob echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" ) > known_hosts echo OK openssh-7.2p2/regress/unittests/hostkeys/test_iterate.c010064400017500001750000000615741267006270000217140ustar00djmdjm/* $OpenBSD: test_iterate.c,v 1.4 2015/03/31 22:59:01 djm Exp $ */ /* * Regress test for hostfile.h hostkeys_foreach() * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include "../test_helper/test_helper.h" #include "sshkey.h" #include "authfile.h" #include "hostfile.h" struct expected { const char *key_file; /* Path for key, NULL for none */ int no_parse_status; /* Expected status w/o key parsing */ int no_parse_keytype; /* Expected keytype w/o key parsing */ int match_host_p; /* Match 'prometheus.example.com' */ int match_host_s; /* Match 'sisyphus.example.com' */ int match_ipv4; /* Match '192.0.2.1' */ int match_ipv6; /* Match '2001:db8::1' */ int match_flags; /* Expected flags from match */ struct hostkey_foreach_line l; /* Expected line contents */ }; struct cbctx { const struct expected *expected; size_t nexpected; size_t i; int flags; int match_host_p; int match_host_s; int match_ipv4; int match_ipv6; }; /* * hostkeys_foreach() iterator callback that verifies the line passed * against an array of expected entries. */ static int check(struct hostkey_foreach_line *l, void *_ctx) { struct cbctx *ctx = (struct cbctx *)_ctx; const struct expected *expected; int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; u_int expected_status, expected_match; int expected_keytype; test_subtest_info("entry %zu/%zu, file line %ld", ctx->i + 1, ctx->nexpected, l->linenum); for (;;) { ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); expected = ctx->expected + ctx->i++; /* If we are matching host/IP then skip entries that don't */ if (!matching) break; if (ctx->match_host_p && expected->match_host_p) break; if (ctx->match_host_s && expected->match_host_s) break; if (ctx->match_ipv4 && expected->match_ipv4) break; if (ctx->match_ipv6 && expected->match_ipv6) break; } expected_status = (parse_key || expected->no_parse_status < 0) ? expected->l.status : (u_int)expected->no_parse_status; expected_match = expected->l.match; #define UPDATE_MATCH_STATUS(x) do { \ if (ctx->x && expected->x) { \ expected_match |= expected->x; \ if (expected_status == HKF_STATUS_OK) \ expected_status = HKF_STATUS_MATCHED; \ } \ } while (0) expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? expected->l.keytype : expected->no_parse_keytype; #ifndef WITH_SSH1 if (parse_key && (expected->l.keytype == KEY_RSA1 || expected->no_parse_keytype == KEY_RSA1)) { expected_status = HKF_STATUS_INVALID; expected_keytype = KEY_UNSPEC; parse_key = 0; } #endif #ifndef OPENSSL_HAS_ECC if (expected->l.keytype == KEY_ECDSA || expected->no_parse_keytype == KEY_ECDSA) { expected_status = HKF_STATUS_INVALID; expected_keytype = KEY_UNSPEC; parse_key = 0; } #endif UPDATE_MATCH_STATUS(match_host_p); UPDATE_MATCH_STATUS(match_host_s); UPDATE_MATCH_STATUS(match_ipv4); UPDATE_MATCH_STATUS(match_ipv6); ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); ASSERT_U_INT_EQ(l->status, expected_status); ASSERT_U_INT_EQ(l->match, expected_match); /* Not all test entries contain fulltext */ if (expected->l.line != NULL) ASSERT_STRING_EQ(l->line, expected->l.line); ASSERT_INT_EQ(l->marker, expected->l.marker); /* XXX we skip hashed hostnames for now; implement checking */ if (expected->l.hosts != NULL) ASSERT_STRING_EQ(l->hosts, expected->l.hosts); /* Not all test entries contain raw keys */ if (expected->l.rawkey != NULL) ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); /* XXX synthesise raw key for cases lacking and compare */ ASSERT_INT_EQ(l->keytype, expected_keytype); if (parse_key) { if (expected->l.key == NULL) ASSERT_PTR_EQ(l->key, NULL); if (expected->l.key != NULL) { ASSERT_PTR_NE(l->key, NULL); ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); } } if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) ASSERT_STRING_EQ(l->comment, expected->l.comment); return 0; } /* Loads public keys for a set of expected results */ static void prepare_expected(struct expected *expected, size_t n) { size_t i; for (i = 0; i < n; i++) { if (expected[i].key_file == NULL) continue; #ifndef WITH_SSH1 if (expected[i].l.keytype == KEY_RSA1) continue; #endif #ifndef OPENSSL_HAS_ECC if (expected[i].l.keytype == KEY_ECDSA) continue; #endif ASSERT_INT_EQ(sshkey_load_public( test_data_file(expected[i].key_file), &expected[i].l.key, NULL), 0); } } struct expected expected_full[] = { { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, /* path, don't care */ 1, /* line number */ HKF_STATUS_COMMENT, /* status */ 0, /* match flags */ "# Plain host keys, plain host names", /* full line, optional */ MRK_NONE, /* marker (CA / revoked) */ NULL, /* hosts text */ NULL, /* raw key, optional */ KEY_UNSPEC, /* key type */ NULL, /* deserialised key */ NULL, /* comment */ } }, { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 2, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #1", } }, { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 3, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #1", } }, { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 4, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #1", } }, { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 5, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #1", } }, { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 6, HKF_STATUS_OK, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #1", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 7, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 8, HKF_STATUS_COMMENT, 0, "# Plain host keys, hostnames + addresses", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 9, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #2", } }, { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 10, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #2", } }, { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 11, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #2", } }, { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 12, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #2", } }, { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 13, HKF_STATUS_OK, 0, NULL, MRK_NONE, "prometheus.example.com,192.0.2.1,2001:db8::1", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #2", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 14, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 15, HKF_STATUS_COMMENT, 0, "# Some hosts with wildcard names / IPs", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 16, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #3", } }, { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 17, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #3", } }, { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 18, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #3", } }, { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 19, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #3", } }, { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, 20, HKF_STATUS_OK, 0, NULL, MRK_NONE, "*.example.com,192.0.2.*,2001:*", NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #3", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 21, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 22, HKF_STATUS_COMMENT, 0, "# Hashed hostname and address entries", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 23, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #5", } }, { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 24, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #5", } }, { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 25, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #5", } }, { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 26, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #5", } }, { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, 27, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #5", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 28, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, /* * The next series have each key listed multiple times, as the * hostname and addresses in the pre-hashed known_hosts are split * to separate lines. */ { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 29, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", } }, { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 30, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", } }, { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 31, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #6", } }, { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 32, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", } }, { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 33, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", } }, { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 34, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #6", } }, { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 35, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", } }, { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 36, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", } }, { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 37, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #6", } }, { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 38, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #6", } }, { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 39, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #6", } }, { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 40, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #6", } }, { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, 41, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", } }, { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, 42, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", } }, { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, 43, HKF_STATUS_OK, 0, NULL, MRK_NONE, NULL, NULL, KEY_RSA, NULL, /* filled at runtime */ "RSA #6", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 44, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 45, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 46, HKF_STATUS_COMMENT, 0, "# Revoked and CA keys", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 47, HKF_STATUS_OK, 0, NULL, MRK_REVOKE, "sisyphus.example.com", NULL, KEY_RSA1, NULL, /* filled at runtime */ "RSA1 #4", } }, { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 48, HKF_STATUS_OK, 0, NULL, MRK_REVOKE, "sisyphus.example.com", NULL, KEY_ED25519, NULL, /* filled at runtime */ "ED25519 #4", } }, { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 49, HKF_STATUS_OK, 0, NULL, MRK_CA, "prometheus.example.com", NULL, KEY_ECDSA, NULL, /* filled at runtime */ "ECDSA #4", } }, { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { NULL, 50, HKF_STATUS_OK, 0, NULL, MRK_CA, "*.example.com", NULL, KEY_DSA, NULL, /* filled at runtime */ "DSA #4", } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 51, HKF_STATUS_COMMENT, 0, "", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 52, HKF_STATUS_COMMENT, 0, "# Some invalid lines", MRK_NONE, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, 53, HKF_STATUS_INVALID, 0, NULL, MRK_ERROR, NULL, NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 54, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 55, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 56, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 57, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 58, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, NULL, } }, { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 59, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, /* filled at runtime */ NULL, } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, 60, HKF_STATUS_INVALID, 0, NULL, MRK_NONE, "sisyphus.example.com", NULL, KEY_UNSPEC, NULL, /* filled at runtime */ NULL, } }, { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, 61, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, MRK_NONE, "prometheus.example.com", NULL, KEY_UNSPEC, NULL, /* filled at runtime */ NULL, } }, }; void test_iterate(void); void test_iterate(void) { struct cbctx ctx; TEST_START("hostkeys_iterate all with key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_PARSE_KEY; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, NULL, NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate all without key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, NULL, NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify host 1"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_p = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_s = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match host 1"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_p = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match host 2"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_s = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify host missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match host missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify addr missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match addr missing"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2 and IPv4"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = 0; ctx.match_host_s = 1; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match host 1 and IPv6"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH; ctx.match_host_p = 1; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_PARSE_KEY; ctx.match_host_s = 1; ctx.match_ipv4 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); TEST_DONE(); TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); memset(&ctx, 0, sizeof(ctx)); ctx.expected = expected_full; ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; ctx.match_host_p = 1; ctx.match_ipv6 = 1; prepare_expected(expected_full, ctx.nexpected); ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); TEST_DONE(); } openssh-7.2p2/regress/unittests/hostkeys/testdata004075500017500001750000000000001267006270000205745ustar00djmdjmopenssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_1.pub010064400017500001750000000011241267006270000223450ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 openssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_2.pub010064400017500001750000000011241267006270000223460ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 openssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_3.pub010064400017500001750000000011241267006270000223470ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 openssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_4.pub010064400017500001750000000011241267006270000223500ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 openssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_5.pub010064400017500001750000000011241267006270000223510ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 openssh-7.2p2/regress/unittests/hostkeys/testdata/dsa_6.pub010064400017500001750000000011241267006270000223520ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_1.pub010064400017500001750000000003261267006270000226600ustar00djmdjmecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_2.pub010064400017500001750000000004061267006270000226600ustar00djmdjmecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_3.pub010064400017500001750000000002521267006270000226600ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_4.pub010064400017500001750000000002521267006270000226610ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_5.pub010064400017500001750000000002521267006270000226620ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 openssh-7.2p2/regress/unittests/hostkeys/testdata/ecdsa_6.pub010064400017500001750000000002521267006270000226630ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_1.pub010064400017500001750000000001341267006270000225740ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_2.pub010064400017500001750000000001341267006270000225750ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_3.pub010064400017500001750000000001341267006270000225760ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_4.pub010064400017500001750000000001341267006270000225770ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_5.pub010064400017500001750000000001341267006270000226000ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 openssh-7.2p2/regress/unittests/hostkeys/testdata/ed25519_6.pub010064400017500001750000000001341267006270000226010ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 openssh-7.2p2/regress/unittests/hostkeys/testdata/known_hosts010064400017500001750000000340471267006270000231570ustar00djmdjm# Plain host keys, plain host names sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 # Plain host keys, hostnames + addresses prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 # Some hosts with wildcard names / IPs *.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 *.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 *.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 *.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 *.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 # Hashed hostname and address entries |1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 |1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 |1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 |1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 |1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 |1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 |1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 |1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 |1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 |1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 |1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 |1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 |1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 |1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 |1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 |1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 |1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 # Revoked and CA keys @revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 @revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 @cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 @cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 # Some invalid lines @what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 sisyphus.example.com prometheus.example.com ssh-ed25519 sisyphus.example.com ssh-dsa AAAATgAAAAdz prometheus.example.com 1024 sisyphus.example.com 1024 65535 prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_1.pub010064400017500001750000000005111267006270000224430ustar00djmdjm1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_2.pub010064400017500001750000000005111267006270000224440ustar00djmdjm1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_3.pub010064400017500001750000000005111267006270000224450ustar00djmdjm1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_4.pub010064400017500001750000000005111267006270000224460ustar00djmdjm1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_5.pub010064400017500001750000000005111267006270000224470ustar00djmdjm1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa1_6.pub010064400017500001750000000005111267006270000224500ustar00djmdjm1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_1.pub010064400017500001750000000003341267006270000223650ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_2.pub010064400017500001750000000003341267006270000223660ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_3.pub010064400017500001750000000003341267006270000223670ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_4.pub010064400017500001750000000003341267006270000223700ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_5.pub010064400017500001750000000003341267006270000223710ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 openssh-7.2p2/regress/unittests/hostkeys/testdata/rsa_6.pub010064400017500001750000000003341267006270000223720ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 openssh-7.2p2/regress/unittests/hostkeys/tests.c010064400017500001750000000003741267006270000203510ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ /* * Regress test for known_hosts-related API. * * Placed in the public domain */ void tests(void); void test_iterate(void); /* test_iterate.c */ void tests(void) { test_iterate(); } openssh-7.2p2/regress/unittests/kex004075500017500001750000000000001267006270000157015ustar00djmdjmopenssh-7.2p2/regress/unittests/kex/Makefile010064400017500001750000000004161267006270000174160ustar00djmdjm# $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $ TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" PROG=test_kex SRCS=tests.c test_kex.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include LDADD+=-lz openssh-7.2p2/regress/unittests/kex/test_kex.c010064400017500001750000000117731267006270000177600ustar00djmdjm/* $OpenBSD: test_kex.c,v 1.2 2015/07/10 06:23:25 markus Exp $ */ /* * Regress test KEX * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include "../test_helper/test_helper.h" #include "ssherr.h" #include "ssh_api.h" #include "sshbuf.h" #include "packet.h" #include "myproposal.h" struct ssh *active_state = NULL; /* XXX - needed for linking */ void kex_tests(void); static int do_debug = 0; static int do_send_and_receive(struct ssh *from, struct ssh *to) { u_char type; size_t len; const u_char *buf; int r; for (;;) { if ((r = ssh_packet_next(from, &type)) != 0) { fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r)); return r; } if (type != 0) return 0; buf = ssh_output_ptr(from, &len); if (do_debug) printf("%zu", len); if (len == 0) return 0; if ((r = ssh_output_consume(from, len)) != 0 || (r = ssh_input_append(to, buf, len)) != 0) return r; } } static void run_kex(struct ssh *client, struct ssh *server) { int r = 0; while (!server->kex->done || !client->kex->done) { if (do_debug) printf(" S:"); if ((r = do_send_and_receive(server, client))) break; if (do_debug) printf(" C:"); if ((r = do_send_and_receive(client, server))) break; } if (do_debug) printf("done: %s\n", ssh_err(r)); ASSERT_INT_EQ(r, 0); ASSERT_INT_EQ(server->kex->done, 1); ASSERT_INT_EQ(client->kex->done, 1); } static void do_kex_with_key(char *kex, int keytype, int bits) { struct ssh *client = NULL, *server = NULL, *server2 = NULL; struct sshkey *private, *public; struct sshbuf *state; struct kex_params kex_params; char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *keyname = NULL; TEST_START("sshkey_generate"); ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); TEST_DONE(); TEST_START("sshkey_from_private"); ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); TEST_DONE(); TEST_START("ssh_init"); memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); if (kex != NULL) kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; keyname = strdup(sshkey_ssh_name(private)); ASSERT_PTR_NE(keyname, NULL); kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0); ASSERT_PTR_NE(client, NULL); ASSERT_PTR_NE(server, NULL); TEST_DONE(); TEST_START("ssh_add_hostkey"); ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0); ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0); TEST_DONE(); TEST_START("kex"); run_kex(client, server); TEST_DONE(); TEST_START("rekeying client"); ASSERT_INT_EQ(kex_send_kexinit(client), 0); run_kex(client, server); TEST_DONE(); TEST_START("rekeying server"); ASSERT_INT_EQ(kex_send_kexinit(server), 0); run_kex(client, server); TEST_DONE(); TEST_START("ssh_packet_get_state"); state = sshbuf_new(); ASSERT_PTR_NE(state, NULL); ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0); ASSERT_INT_GE(sshbuf_len(state), 1); TEST_DONE(); TEST_START("ssh_packet_set_state"); server2 = NULL; ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0); ASSERT_PTR_NE(server2, NULL); ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0); kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */ ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0); ASSERT_INT_EQ(sshbuf_len(state), 0); sshbuf_free(state); ASSERT_PTR_NE(server2->kex, NULL); /* XXX we need to set the callbacks */ server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; #ifdef OPENSSL_HAS_ECC server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; #endif server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server; server2->kex->load_host_public_key = server->kex->load_host_public_key; server2->kex->load_host_private_key = server->kex->load_host_private_key; server2->kex->sign = server->kex->sign; TEST_DONE(); TEST_START("rekeying server2"); ASSERT_INT_EQ(kex_send_kexinit(server2), 0); run_kex(client, server2); ASSERT_INT_EQ(kex_send_kexinit(client), 0); run_kex(client, server2); TEST_DONE(); TEST_START("cleanup"); sshkey_free(private); sshkey_free(public); ssh_free(client); ssh_free(server); ssh_free(server2); free(keyname); TEST_DONE(); } static void do_kex(char *kex) { do_kex_with_key(kex, KEY_RSA, 2048); do_kex_with_key(kex, KEY_DSA, 1024); #ifdef OPENSSL_HAS_ECC do_kex_with_key(kex, KEY_ECDSA, 256); #endif do_kex_with_key(kex, KEY_ED25519, 256); } void kex_tests(void) { do_kex("curve25519-sha256@libssh.org"); #ifdef OPENSSL_HAS_ECC do_kex("ecdh-sha2-nistp256"); do_kex("ecdh-sha2-nistp384"); do_kex("ecdh-sha2-nistp521"); #endif do_kex("diffie-hellman-group-exchange-sha256"); do_kex("diffie-hellman-group-exchange-sha1"); do_kex("diffie-hellman-group14-sha1"); do_kex("diffie-hellman-group1-sha1"); } openssh-7.2p2/regress/unittests/kex/tests.c010064400017500001750000000003121267006270000172570ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ /* * Placed in the public domain */ #include "../test_helper/test_helper.h" void kex_tests(void); void tests(void) { kex_tests(); } openssh-7.2p2/regress/unittests/sshbuf004075500017500001750000000000001267006270000164045ustar00djmdjmopenssh-7.2p2/regress/unittests/sshbuf/Makefile010064400017500001750000000004671267006270000201270ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ PROG=test_sshbuf SRCS=tests.c SRCS+=test_sshbuf.c SRCS+=test_sshbuf_getput_basic.c SRCS+=test_sshbuf_getput_crypto.c SRCS+=test_sshbuf_misc.c SRCS+=test_sshbuf_fuzz.c SRCS+=test_sshbuf_getput_fuzz.c SRCS+=test_sshbuf_fixed.c .include openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf.c010064400017500001750000000144771267006270000211720ustar00djmdjm/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #define SSHBUF_INTERNAL 1 /* access internals for testing */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" void sshbuf_tests(void); void sshbuf_tests(void) { struct sshbuf *p1; const u_char *cdp; u_char *dp; size_t sz; int r; TEST_START("allocate sshbuf"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); TEST_DONE(); TEST_START("max size on fresh buffer"); ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0); TEST_DONE(); TEST_START("available on fresh buffer"); ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0); TEST_DONE(); TEST_START("len = 0 on empty buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); TEST_DONE(); TEST_START("set valid max size"); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536); TEST_DONE(); TEST_START("available on limited buffer"); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536); TEST_DONE(); TEST_START("free"); sshbuf_free(p1); TEST_DONE(); TEST_START("consume on empty buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("consume_end on empty buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0); ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("reserve space"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp = 0x11; r = sshbuf_reserve(p1, 3, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp++ = 0x22; *dp++ = 0x33; *dp++ = 0x44; TEST_DONE(); TEST_START("sshbuf_len on filled buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); TEST_DONE(); TEST_START("sshbuf_ptr on filled buffer"); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_U8_EQ(cdp[0], 0x11); ASSERT_U8_EQ(cdp[1], 0x22); ASSERT_U8_EQ(cdp[2], 0x33); ASSERT_U8_EQ(cdp[3], 0x44); TEST_DONE(); TEST_START("consume on filled buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); r = sshbuf_consume(p1, 64); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(p1, NULL); ASSERT_U8_EQ(cdp[0], 0x22); ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(p1, NULL); ASSERT_U8_EQ(cdp[0], 0x44); r = sshbuf_consume(p1, 2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); r = sshbuf_consume(p1, 1); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("consume_end on filled buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_reserve(p1, 4, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp++ = 0x11; *dp++ = 0x22; *dp++ = 0x33; *dp++ = 0x44; ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); r = sshbuf_consume_end(p1, 5); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_U8_EQ(*cdp, 0x11); r = sshbuf_consume_end(p1, 2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("fill limited buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); r = sshbuf_reserve(p1, 1223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0xd7, 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_PTR_EQ(dp, NULL); TEST_DONE(); TEST_START("consume and force compaction"); ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); r = sshbuf_reserve(p1, 224, &dp); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_PTR_EQ(dp, NULL); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); r = sshbuf_reserve(p1, 223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0x7d, 223); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); TEST_DONE(); TEST_START("resize full buffer"); r = sshbuf_set_max_size(p1, 1000); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223); ASSERT_INT_EQ(sshbuf_len(p1), 1223); TEST_DONE(); /* NB. uses sshbuf internals */ TEST_START("alloc chunking"); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp = 0xff; cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1); ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0); sshbuf_free(p1); TEST_DONE(); TEST_START("reset buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); r = sshbuf_reserve(p1, 1223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0xd7, 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); sshbuf_reset(p1); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); sshbuf_free(p1); TEST_DONE(); } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_fixed.c010064400017500001750000000074571267006270000223510ustar00djmdjm/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #define SSHBUF_INTERNAL 1 /* access internals for testing */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include "../test_helper/test_helper.h" #include "sshbuf.h" #include "ssherr.h" void sshbuf_fixed(void); const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello"; void sshbuf_fixed(void) { struct sshbuf *p1, *p2, *p3; u_char c; char *s; u_int i; size_t l; TEST_START("sshbuf_from"); p1 = sshbuf_from(test_buf, sizeof(test_buf)); ASSERT_PTR_NE(p1, NULL); ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL); ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY); ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_from data"); p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1); ASSERT_PTR_NE(p1, NULL); ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf); ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0); ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1); ASSERT_U8_EQ(c, 1); ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0); ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5); ASSERT_U32_EQ(i, 0x12345678); ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); ASSERT_STRING_EQ(s, "hello"); ASSERT_SIZE_T_EQ(l, 5); sshbuf_free(p1); free(s); TEST_DONE(); TEST_START("sshbuf_fromb "); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1); ASSERT_PTR_EQ(sshbuf_parent(p1), NULL); ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0); p2 = sshbuf_fromb(p1); ASSERT_PTR_NE(p2, NULL); ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2); ASSERT_PTR_EQ(sshbuf_parent(p1), NULL); ASSERT_PTR_EQ(sshbuf_parent(p2), p1); ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1)); ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_PTR_NE(sshbuf_ptr(p2), NULL); ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL); ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2)); ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0); ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1); ASSERT_U8_EQ(c, 1); ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0); ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5); ASSERT_U32_EQ(i, 0x12345678); ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0); ASSERT_STRING_EQ(s, "hello"); ASSERT_SIZE_T_EQ(l, 5); sshbuf_free(p1); ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1); sshbuf_free(p2); free(s); TEST_DONE(); TEST_START("sshbuf_froms"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0); p2 = sshbuf_new(); ASSERT_PTR_NE(p2, NULL); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1); ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1); ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0); ASSERT_PTR_NE(p3, NULL); ASSERT_PTR_NE(sshbuf_ptr(p3), NULL); ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1); ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1); sshbuf_free(p3); ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0); ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0); ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_PTR_EQ(p3, NULL); sshbuf_free(p2); sshbuf_free(p1); } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_fuzz.c010064400017500001750000000064141267006270000222400ustar00djmdjm/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" #define NUM_FUZZ_TESTS (1 << 18) void sshbuf_fuzz_tests(void); void sshbuf_fuzz_tests(void) { struct sshbuf *p1; u_char *dp; size_t sz, sz2, i; u_int32_t r; int ret; /* NB. uses sshbuf internals */ TEST_START("fuzz alloc/dealloc"); p1 = sshbuf_new(); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0); ASSERT_PTR_NE(p1, NULL); ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); for (i = 0; i < NUM_FUZZ_TESTS; i++) { r = arc4random_uniform(10); if (r == 0) { /* 10% chance: small reserve */ r = arc4random_uniform(10); fuzz_reserve: sz = sshbuf_avail(p1); sz2 = sshbuf_len(p1); ret = sshbuf_reserve(p1, r, &dp); if (ret < 0) { ASSERT_PTR_EQ(dp, NULL); ASSERT_SIZE_T_LT(sz, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); } else { ASSERT_PTR_NE(dp, NULL); ASSERT_SIZE_T_GE(sz, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r); memset(dp, arc4random_uniform(255) + 1, r); } } else if (r < 3) { /* 20% chance: big reserve */ r = arc4random_uniform(8 * 1024); goto fuzz_reserve; } else if (r == 3) { /* 10% chance: small consume */ r = arc4random_uniform(10); fuzz_consume: sz = sshbuf_avail(p1); sz2 = sshbuf_len(p1); /* 50% change consume from end, otherwise start */ ret = ((arc4random() & 1) ? sshbuf_consume : sshbuf_consume_end)(p1, r); if (ret < 0) { ASSERT_SIZE_T_LT(sz2, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); } else { ASSERT_SIZE_T_GE(sz2, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r); } } else if (r < 8) { /* 40% chance: big consume */ r = arc4random_uniform(2 * 1024); goto fuzz_consume; } else if (r == 8) { /* 10% chance: reset max size */ r = arc4random_uniform(16 * 1024); sz = sshbuf_max_size(p1); if (sshbuf_set_max_size(p1, r) < 0) ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); else ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r); } else { if (arc4random_uniform(8192) == 0) { /* tiny chance: new buffer */ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); sshbuf_free(p1); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0); } else { /* Almost 10%: giant reserve */ /* use arc4random_buf for r > 2^32 on 64 bit */ arc4random_buf(&r, sizeof(r)); while (r < SSHBUF_SIZE_MAX / 2) { r <<= 1; r |= arc4random() & 1; } goto fuzz_reserve; } } ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024); } ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); sshbuf_free(p1); TEST_DONE(); } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_getput_basic.c010064400017500001750000000334001267006270000237060ustar00djmdjm/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" void sshbuf_getput_basic_tests(void); void sshbuf_getput_basic_tests(void) { struct sshbuf *p1, *p2; const u_char *cd; u_char *d, d2[32], x[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99 }; u_int64_t v64; u_int32_t v32; u_int16_t v16; u_char v8; size_t s; char *s2; int r; u_char bn1[] = { 0x00, 0x00, 0x00 }; u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 }; u_char bn3[] = { 0x00, 0x80, 0x09 }; u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 }; u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 }; u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 }; TEST_START("PEEK_U64"); ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL); TEST_DONE(); TEST_START("PEEK_U32"); ASSERT_U32_EQ(PEEK_U32(x), 0x11223344); TEST_DONE(); TEST_START("PEEK_U16"); ASSERT_U16_EQ(PEEK_U16(x), 0x1122); TEST_DONE(); TEST_START("POKE_U64"); bzero(d2, sizeof(d2)); POKE_U64(d2, 0x1122334455667788ULL); ASSERT_MEM_EQ(d2, x, 8); TEST_DONE(); TEST_START("POKE_U32"); bzero(d2, sizeof(d2)); POKE_U32(d2, 0x11223344); ASSERT_MEM_EQ(d2, x, 4); TEST_DONE(); TEST_START("POKE_U16"); bzero(d2, sizeof(d2)); POKE_U16(d2, 0x1122); ASSERT_MEM_EQ(d2, x, 2); TEST_DONE(); TEST_START("sshbuf_put"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); cd = sshbuf_ptr(p1); ASSERT_PTR_NE(cd, NULL); ASSERT_U8_EQ(cd[0], 0x11); ASSERT_U8_EQ(cd[1], 0x22); ASSERT_U8_EQ(cd[2], 0x33); ASSERT_U8_EQ(cd[3], 0x44); ASSERT_U8_EQ(cd[4], 0x55); TEST_DONE(); TEST_START("sshbuf_get"); ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0); ASSERT_MEM_EQ(d2, x, 4); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55); TEST_DONE(); TEST_START("sshbuf_get truncated"); r = sshbuf_get(p1, d2, 4); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55); TEST_DONE(); TEST_START("sshbuf_put truncated"); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0); r = sshbuf_put(p1, x, 5); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_u64"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10); ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0); ASSERT_U64_EQ(v64, 0x1122334455667788ULL); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); TEST_DONE(); TEST_START("sshbuf_get_u64 truncated"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); r = sshbuf_get_u64(p1, &v64); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_u32"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10); ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0); ASSERT_U32_EQ(v32, 0x11223344); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6); ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0); ASSERT_U32_EQ(v32, 0x55667788); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); TEST_DONE(); TEST_START("sshbuf_get_u32 truncated"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); r = sshbuf_get_u32(p1, &v32); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_u16"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9); ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); ASSERT_U16_EQ(v16, 0x1122); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7); ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); ASSERT_U16_EQ(v16, 0x3344); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); ASSERT_U16_EQ(v16, 0x5566); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0); ASSERT_U16_EQ(v16, 0x7788); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); TEST_DONE(); TEST_START("sshbuf_get_u16 truncated"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); r = sshbuf_get_u16(p1, &v16); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_u8"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0); ASSERT_U8_EQ(v8, 0x11); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0); ASSERT_U8_EQ(v8, 0x22); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); TEST_DONE(); TEST_START("sshbuf_get_u8 truncated"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); r = sshbuf_get_u8(p1, &v8); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u64"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u64 exact"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0); ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u64 limited"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0); r = sshbuf_put_u64(p1, 0x1122334455667788ULL); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u32"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u32 exact"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u32 limited"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0); r = sshbuf_put_u32(p1, 0x11223344); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u16"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u16"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_u16 limited"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0); r = sshbuf_put_u16(p1, 0x1122); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_string"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4); ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0); ASSERT_SIZE_T_EQ(s, sizeof(x)); ASSERT_MEM_EQ(d, x, sizeof(x)); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); free(d); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_string exact"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0); ASSERT_SIZE_T_EQ(s, sizeof(x)); ASSERT_MEM_EQ(d, x, sizeof(x)); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); free(d); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_string truncated"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3); r = sshbuf_get_string(p1, &d, &s); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_string giant"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); r = sshbuf_get_string(p1, &d, &s); ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_cstring giant"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); r = sshbuf_get_cstring(p1, &s2, &s); ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_cstring embedded \\0"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); r = sshbuf_get_cstring(p1, &s2, NULL); ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_cstring trailing \\0"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0); ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1); ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0); ASSERT_SIZE_T_EQ(s, sizeof(x) - 1); ASSERT_MEM_EQ(s2, x, s); free(s2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_string"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4); ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x)); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_string limited"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0); r = sshbuf_put_string(p1, x, sizeof(x)); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_string giant"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_putf"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f); ASSERT_INT_EQ(r, 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11); ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_putb"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); p2 = sshbuf_new(); ASSERT_PTR_NE(p2, NULL); ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0); ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0); sshbuf_free(p1); ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12); ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12); sshbuf_free(p2); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes empty buf"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes all zeroes"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes simple"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes leading zero"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes neg"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3)); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2_bytes neg and leading zero"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3)); ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3)); sshbuf_free(p1); TEST_DONE(); } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c010064400017500001750000000275461267006270000241630ustar00djmdjm/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include #include #ifdef OPENSSL_HAS_NISTP256 # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" void sshbuf_getput_crypto_tests(void); void sshbuf_getput_crypto_tests(void) { struct sshbuf *p1; BIGNUM *bn, *bn2; /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; /* This one has MSB set to test bignum2 encoding negative-avoidance */ const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11"; u_char expbn1[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }; u_char expbn2[] = { 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x7f, 0xff, 0x11 }; #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) const u_char *d; size_t s; BIGNUM *bn_x, *bn_y; int ec256_nid = NID_X9_62_prime256v1; char *ec256_x = "0C828004839D0106AA59575216191357" "34B451459DADB586677EF9DF55784999"; char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2" "C8F9A35E42BDD047550F69D80EC23CD4"; u_char expec256[] = { 0x04, 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4 }; EC_KEY *eck; EC_POINT *ecp; #endif int r; #define MKBN(b, bnn) \ do { \ bnn = NULL; \ ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \ } while (0) TEST_START("sshbuf_put_bignum1"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2); ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1)); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum1 limited"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); r = sshbuf_put_bignum1(p1, bn); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum1 bn2"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2); ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2)); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum1 bn2 limited"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); r = sshbuf_put_bignum1(p1, bn); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4); ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn)); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1)); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2 limited"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0); r = sshbuf_put_bignum2(p1, bn); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2 bn2"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */ ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1); ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2)); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_put_bignum2 bn2 limited"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0); r = sshbuf_put_bignum2(p1, bn); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); BN_free(bn); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum1"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1)); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); bn2 = BN_new(); ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); ASSERT_BIGNUM_EQ(bn, bn2); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum1 truncated"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); bn2 = BN_new(); r = sshbuf_get_bignum1(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum1 giant"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0); ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); bn2 = BN_new(); r = sshbuf_get_bignum1(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum1 bn2"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2)); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); bn2 = BN_new(); ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); ASSERT_BIGNUM_EQ(bn, bn2); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum1 bn2 truncated"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); bn2 = BN_new(); r = sshbuf_get_bignum1(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1)); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); bn2 = BN_new(); ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); ASSERT_BIGNUM_EQ(bn, bn2); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2 truncated"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); bn2 = BN_new(); r = sshbuf_get_bignum2(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2 giant"); MKBN(hexbn1, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0); ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0); bn2 = BN_new(); r = sshbuf_get_bignum2(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2 bn2"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2)); ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); bn2 = BN_new(); ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); ASSERT_BIGNUM_EQ(bn, bn2); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2 bn2 truncated"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); bn2 = BN_new(); r = sshbuf_get_bignum2(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_get_bignum2 bn2 negative"); MKBN(hexbn2, bn); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); bn2 = BN_new(); r = sshbuf_get_bignum2(p1, bn2); ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4); BN_free(bn); BN_free(bn2); sshbuf_free(p1); TEST_DONE(); #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) TEST_START("sshbuf_put_ec"); eck = EC_KEY_new_by_curve_name(ec256_nid); ASSERT_PTR_NE(eck, NULL); ecp = EC_POINT_new(EC_KEY_get0_group(eck)); ASSERT_PTR_NE(ecp, NULL); MKBN(ec256_x, bn_x); MKBN(ec256_y, bn_y); ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); BN_free(bn_x); BN_free(bn_y); EC_POINT_free(ecp); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0); ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0); ASSERT_SIZE_T_EQ(s, sizeof(expec256)); ASSERT_MEM_EQ(d, expec256, sizeof(expec256)); sshbuf_free(p1); EC_KEY_free(eck); TEST_DONE(); TEST_START("sshbuf_get_ec"); eck = EC_KEY_new_by_curve_name(ec256_nid); ASSERT_PTR_NE(eck, NULL); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); bn_x = BN_new(); bn_y = BN_new(); ASSERT_PTR_NE(bn_x, NULL); ASSERT_PTR_NE(bn_y, NULL); ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), bn_x, bn_y, NULL), 1); MKBN(ec256_x, bn); MKBN(ec256_y, bn2); ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0); ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); sshbuf_free(p1); EC_KEY_free(eck); BN_free(bn_x); BN_free(bn_y); BN_free(bn); BN_free(bn2); TEST_DONE(); #endif } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c010064400017500001750000000057151267006270000236330ustar00djmdjm/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include #include #ifdef OPENSSL_HAS_NISTP256 # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" void sshbuf_getput_fuzz_tests(void); static void attempt_parse_blob(u_char *blob, size_t len) { struct sshbuf *p1; BIGNUM *bn; #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) EC_KEY *eck; #endif u_char *s; size_t l; u_int8_t u8; u_int16_t u16; u_int32_t u32; u_int64_t u64; p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0); sshbuf_get_u8(p1, &u8); sshbuf_get_u16(p1, &u16); sshbuf_get_u32(p1, &u32); sshbuf_get_u64(p1, &u64); if (sshbuf_get_string(p1, &s, &l) == 0) { bzero(s, l); free(s); } bn = BN_new(); sshbuf_get_bignum1(p1, bn); BN_clear_free(bn); bn = BN_new(); sshbuf_get_bignum2(p1, bn); BN_clear_free(bn); #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ASSERT_PTR_NE(eck, NULL); sshbuf_get_eckey(p1, eck); EC_KEY_free(eck); #endif sshbuf_free(p1); } static void onerror(void *fuzz) { fprintf(stderr, "Failed during fuzz:\n"); fuzz_dump((struct fuzz *)fuzz); } void sshbuf_getput_fuzz_tests(void) { u_char blob[] = { /* u8 */ 0xd0, /* u16 */ 0xc0, 0xde, /* u32 */ 0xfa, 0xce, 0xde, 0xad, /* u64 */ 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef, /* string */ 0x00, 0x00, 0x00, 0x09, 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!', /* bignum1 */ 0x79, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* bignum2 */ 0x00, 0x00, 0x00, 0x14, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x7f, 0xff, 0x11, /* EC point (NIST-256 curve) */ 0x00, 0x00, 0x00, 0x41, 0x04, 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4, }; struct fuzz *fuzz; TEST_START("fuzz blob parsing"); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP | FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob)); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) attempt_parse_blob(blob, sizeof(blob)); fuzz_cleanup(fuzz); TEST_DONE(); TEST_ONERROR(NULL, NULL); } openssh-7.2p2/regress/unittests/sshbuf/test_sshbuf_misc.c010064400017500001750000000061471267006270000222000ustar00djmdjm/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include "../test_helper/test_helper.h" #include "sshbuf.h" void sshbuf_misc_tests(void); void sshbuf_misc_tests(void) { struct sshbuf *p1; char tmp[512], *p; FILE *out; size_t sz; TEST_START("sshbuf_dump"); out = tmpfile(); ASSERT_PTR_NE(out, NULL); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); sshbuf_dump(p1, out); fflush(out); rewind(out); sz = fread(tmp, 1, sizeof(tmp), out); ASSERT_INT_EQ(ferror(out), 0); ASSERT_INT_NE(feof(out), 0); ASSERT_SIZE_T_GT(sz, 0); tmp[sz] = '\0'; ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL); fclose(out); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_dtob16"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0); p = sshbuf_dtob16(p1); ASSERT_PTR_NE(p, NULL); ASSERT_STRING_EQ(p, "12345678"); free(p); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_dtob64 len 1"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); p = sshbuf_dtob64(p1); ASSERT_PTR_NE(p, NULL); ASSERT_STRING_EQ(p, "EQ=="); free(p); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_dtob64 len 2"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0); p = sshbuf_dtob64(p1); ASSERT_PTR_NE(p, NULL); ASSERT_STRING_EQ(p, "ESI="); free(p); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_dtob64 len 3"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0); ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0); p = sshbuf_dtob64(p1); ASSERT_PTR_NE(p, NULL); ASSERT_STRING_EQ(p, "ESIz"); free(p); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_dtob64 len 8191"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0); bzero(sshbuf_mutable_ptr(p1), 8192); p = sshbuf_dtob64(p1); ASSERT_PTR_NE(p, NULL); ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4); free(p); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_b64tod len 1"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_b64tod len 2"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f); sshbuf_free(p1); TEST_DONE(); TEST_START("sshbuf_b64tod len 4"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f); sshbuf_free(p1); TEST_DONE(); } openssh-7.2p2/regress/unittests/sshbuf/tests.c010064400017500001750000000011261267006270000177660ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "../test_helper/test_helper.h" void sshbuf_tests(void); void sshbuf_getput_basic_tests(void); void sshbuf_getput_crypto_tests(void); void sshbuf_misc_tests(void); void sshbuf_fuzz_tests(void); void sshbuf_getput_fuzz_tests(void); void sshbuf_fixed(void); void tests(void) { sshbuf_tests(); sshbuf_getput_basic_tests(); sshbuf_getput_crypto_tests(); sshbuf_misc_tests(); sshbuf_fuzz_tests(); sshbuf_getput_fuzz_tests(); sshbuf_fixed(); } openssh-7.2p2/regress/unittests/sshkey004075500017500001750000000000001267006270000164205ustar00djmdjmopenssh-7.2p2/regress/unittests/sshkey/Makefile010064400017500001750000000005001267006270000201270ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2014/06/24 01:14:18 djm Exp $ TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" PROG=test_sshkey SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata .include openssh-7.2p2/regress/unittests/sshkey/common.c010064400017500001750000000031551267006270000201340ustar00djmdjm/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */ /* * Helpers for key API tests * * Placed in the public domain */ #include "includes.h" #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include #include #ifdef OPENSSL_HAS_NISTP256 # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "authfile.h" #include "sshkey.h" #include "sshbuf.h" #include "common.h" struct sshbuf * load_file(const char *name) { int fd; struct sshbuf *ret; ASSERT_PTR_NE(ret = sshbuf_new(), NULL); ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0); close(fd); return ret; } struct sshbuf * load_text_file(const char *name) { struct sshbuf *ret = load_file(name); const u_char *p; /* Trim whitespace at EOL */ for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) { if (p[sshbuf_len(ret) - 1] == '\r' || p[sshbuf_len(ret) - 1] == '\t' || p[sshbuf_len(ret) - 1] == ' ' || p[sshbuf_len(ret) - 1] == '\n') ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0); else break; } /* \0 terminate */ ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0); return ret; } BIGNUM * load_bignum(const char *name) { BIGNUM *ret = NULL; struct sshbuf *buf; buf = load_text_file(name); ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0); sshbuf_free(buf); return ret; } openssh-7.2p2/regress/unittests/sshkey/common.h010064400017500001750000000005701267006270000201370ustar00djmdjm/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */ /* * Helpers for key API tests * * Placed in the public domain */ /* Load a binary file into a buffer */ struct sshbuf *load_file(const char *name); /* Load a text file into a buffer */ struct sshbuf *load_text_file(const char *name); /* Load a bignum from a file */ BIGNUM *load_bignum(const char *name); openssh-7.2p2/regress/unittests/sshkey/mktestdata.sh010075500017500001750000000145141267006270000212010ustar00djmdjm#!/bin/sh # $OpenBSD: mktestdata.sh,v 1.5 2015/07/07 14:53:30 markus Exp $ PW=mekmitasdigoat rsa1_params() { _in="$1" _outbase="$2" set -e ssh-keygen -f $_in -e -m pkcs8 | \ openssl rsa -noout -text -pubin | \ awk '/^Modulus:$/,/^Exponent:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n # XXX need conversion support in ssh-keygen for the other params for x in n ; do echo "" >> ${_outbase}.$x echo ============ ${_outbase}.$x cat ${_outbase}.$x echo ============ done } rsa_params() { _in="$1" _outbase="$2" set -e openssl rsa -noout -text -in $_in | \ awk '/^modulus:$/,/^publicExponent:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n openssl rsa -noout -text -in $_in | \ awk '/^prime1:$/,/^prime2:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.p openssl rsa -noout -text -in $_in | \ awk '/^prime2:$/,/^exponent1:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.q for x in n p q ; do echo "" >> ${_outbase}.$x echo ============ ${_outbase}.$x cat ${_outbase}.$x echo ============ done } dsa_params() { _in="$1" _outbase="$2" set -e openssl dsa -noout -text -in $_in | \ awk '/^priv:$/,/^pub:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv openssl dsa -noout -text -in $_in | \ awk '/^pub:/,/^P:/' | #\ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub openssl dsa -noout -text -in $_in | \ awk '/^G:/,0' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g for x in priv pub g ; do echo "" >> ${_outbase}.$x echo ============ ${_outbase}.$x cat ${_outbase}.$x echo ============ done } ecdsa_params() { _in="$1" _outbase="$2" set -e openssl ec -noout -text -in $_in | \ awk '/^priv:$/,/^pub:/' | \ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv openssl ec -noout -text -in $_in | \ awk '/^pub:/,/^ASN1 OID:/' | #\ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub openssl ec -noout -text -in $_in | \ grep "ASN1 OID:" | tr -d '\n' | \ sed 's/.*: //;s/ *$//' > ${_outbase}.curve for x in priv pub curve ; do echo "" >> ${_outbase}.$x echo ============ ${_outbase}.$x cat ${_outbase}.$x echo ============ done } set -ex cd testdata rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1 rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2 rm -f rsa_n dsa_n ecdsa_n # new-format keys rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb ssh-keygen -t rsa1 -b 1024 -C "RSA1 test key #1" -N "" -f rsa1_1 ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2 ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_2 cp rsa_1 rsa_n cp dsa_1 dsa_n cp ecdsa_1 ecdsa_n cp rsa1_1 rsa1_1_pw cp rsa_1 rsa_1_pw cp dsa_1 dsa_1_pw cp ecdsa_1 ecdsa_1_pw cp ed25519_1 ed25519_1_pw cp rsa_1 rsa_n_pw cp dsa_1 dsa_n_pw cp ecdsa_1 ecdsa_n_pw ssh-keygen -pf rsa1_1_pw -N "$PW" ssh-keygen -pf rsa_1_pw -N "$PW" ssh-keygen -pf dsa_1_pw -N "$PW" ssh-keygen -pf ecdsa_1_pw -N "$PW" ssh-keygen -pf ed25519_1_pw -N "$PW" ssh-keygen -opf rsa_n_pw -N "$PW" ssh-keygen -opf dsa_n_pw -N "$PW" ssh-keygen -opf ecdsa_n_pw -N "$PW" rsa1_params rsa1_1 rsa1_1.param rsa1_params rsa1_2 rsa1_2.param rsa_params rsa_1 rsa_1.param rsa_params rsa_2 rsa_2.param dsa_params dsa_1 dsa_1.param dsa_params dsa_1 dsa_1.param ecdsa_params ecdsa_1 ecdsa_1.param ecdsa_params ecdsa_2 ecdsa_2.param # XXX ed25519 params ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 1 rsa_1.pub ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 2 dsa_1.pub ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 3 ecdsa_1.pub ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 4 ed25519_1.pub ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 5 rsa_1.pub ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 6 dsa_1.pub ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 7 ecdsa_1.pub ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 8 ed25519_1.pub ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb # XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against) echo "$PW" > pw openssh-7.2p2/regress/unittests/sshkey/test_file.c010064400017500001750000000305531267006270000206240ustar00djmdjm/* $OpenBSD: test_file.c,v 1.5 2015/10/06 01:20:59 djm Exp $ */ /* * Regress test for sshkey.h key management API * * Placed in the public domain */ #include "includes.h" #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include #include #ifdef OPENSSL_HAS_NISTP256 # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "authfile.h" #include "sshkey.h" #include "sshbuf.h" #include "digest.h" #include "common.h" void sshkey_file_tests(void); void sshkey_file_tests(void) { struct sshkey *k1, *k2; struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; char *cp; TEST_START("load passphrase"); pw = load_text_file("pw"); TEST_DONE(); #ifdef WITH_SSH1 TEST_START("parse RSA1 from private"); buf = load_file("rsa1_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa1_1.param.n"); ASSERT_BIGNUM_EQ(k1->rsa->n, a); BN_free(a); TEST_DONE(); TEST_START("parse RSA1 from private w/ passphrase"); buf = load_file("rsa1_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA1 from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("RSA1 key hex fingerprint"); buf = load_text_file("rsa1_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("RSA1 key bubblebabble fingerprint"); buf = load_text_file("rsa1_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #endif TEST_START("parse RSA from private"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa_1.param.n"); b = load_bignum("rsa_1.param.p"); c = load_bignum("rsa_1.param.q"); ASSERT_BIGNUM_EQ(k1->rsa->n, a); ASSERT_BIGNUM_EQ(k1->rsa->p, b); ASSERT_BIGNUM_EQ(k1->rsa->q, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse RSA from private w/ passphrase"); buf = load_file("rsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format"); buf = load_file("rsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format w/ passphrase"); buf = load_file("rsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_RSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("RSA key hex fingerprint"); buf = load_text_file("rsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("RSA cert hex fingerprint"); buf = load_text_file("rsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("RSA key bubblebabble fingerprint"); buf = load_text_file("rsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); TEST_START("parse DSA from private"); buf = load_file("dsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("dsa_1.param.g"); b = load_bignum("dsa_1.param.priv"); c = load_bignum("dsa_1.param.pub"); ASSERT_BIGNUM_EQ(k1->dsa->g, a); ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse DSA from private w/ passphrase"); buf = load_file("dsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format"); buf = load_file("dsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format w/ passphrase"); buf = load_file("dsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("DSA key hex fingerprint"); buf = load_text_file("dsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("DSA cert hex fingerprint"); buf = load_text_file("dsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("DSA key bubblebabble fingerprint"); buf = load_text_file("dsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); buf = load_text_file("ecdsa_1.param.curve"); ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf), OBJ_nid2sn(k1->ecdsa_nid)); sshbuf_free(buf); a = load_bignum("ecdsa_1.param.priv"); b = load_bignum("ecdsa_1.param.pub"); c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); ASSERT_PTR_NE(c, NULL); ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); ASSERT_BIGNUM_EQ(b, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse ECDSA from private w/ passphrase"); buf = load_file("ecdsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format"); buf = load_file("ecdsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format w/ passphrase"); buf = load_file("ecdsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("ECDSA key hex fingerprint"); buf = load_text_file("ecdsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("ECDSA cert hex fingerprint"); buf = load_text_file("ecdsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("ECDSA key bubblebabble fingerprint"); buf = load_text_file("ecdsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #endif /* OPENSSL_HAS_ECC */ TEST_START("parse Ed25519 from private"); buf = load_file("ed25519_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); ASSERT_INT_EQ(k1->type, KEY_ED25519); /* XXX check key contents */ TEST_DONE(); TEST_START("parse Ed25519 from private w/ passphrase"); buf = load_file("ed25519_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("Ed25519 key hex fingerprint"); buf = load_text_file("ed25519_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("Ed25519 cert hex fingerprint"); buf = load_text_file("ed25519_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("Ed25519 key bubblebabble fingerprint"); buf = load_text_file("ed25519_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); sshbuf_free(pw); } openssh-7.2p2/regress/unittests/sshkey/test_fuzz.c010064400017500001750000000254601267006270000207040ustar00djmdjm/* $OpenBSD: test_fuzz.c,v 1.6 2015/12/07 02:20:46 djm Exp $ */ /* * Fuzz tests for key parsing * * Placed in the public domain */ #include "includes.h" #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include #include #ifdef OPENSSL_HAS_NISTP256 # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "authfile.h" #include "sshkey.h" #include "sshbuf.h" #include "common.h" void sshkey_fuzz_tests(void); static void onerror(void *fuzz) { fprintf(stderr, "Failed during fuzz:\n"); fuzz_dump((struct fuzz *)fuzz); } static void public_fuzz(struct sshkey *k) { struct sshkey *k1; struct sshbuf *buf; struct fuzz *fuzz; ASSERT_PTR_NE(buf = sshbuf_new(), NULL); ASSERT_INT_EQ(sshkey_putb(k, buf), 0); /* XXX need a way to run the tests in "slow, but complete" mode */ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf), &k1), 0); sshkey_free(k1); sshbuf_free(buf); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0) sshkey_free(k1); } fuzz_cleanup(fuzz); } static void sig_fuzz(struct sshkey *k, const char *sig_alg) { struct fuzz *fuzz; u_char *sig, c[] = "some junk to be signed"; size_t l; ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), sig_alg, 0), 0); ASSERT_SIZE_T_GT(l, 0); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l); ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0); free(sig); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { /* Ensure 1-bit difference at least */ if (fuzz_matches_original(fuzz)) continue; ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), c, sizeof(c), 0), 0); } fuzz_cleanup(fuzz); } void sshkey_fuzz_tests(void) { struct sshkey *k1; struct sshbuf *buf, *fuzzed; struct fuzz *fuzz; int r; #ifdef WITH_SSH1 TEST_START("fuzz RSA1 private"); buf = load_file("rsa1_1"); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz RSA1 public"); buf = load_file("rsa1_1_pw"); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); #endif TEST_START("fuzz RSA private"); buf = load_file("rsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz RSA new-format private"); buf = load_file("rsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz DSA private"); buf = load_file("dsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz DSA new-format private"); buf = load_file("dsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA private"); buf = load_file("ecdsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz ECDSA new-format private"); buf = load_file("ecdsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); #endif TEST_START("fuzz Ed25519 private"); buf = load_file("ed25519_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); TEST_START("fuzz RSA public"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz RSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz DSA public"); buf = load_file("dsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz DSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA public"); buf = load_file("ecdsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz ECDSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); #endif TEST_START("fuzz Ed25519 public"); buf = load_file("ed25519_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz Ed25519 cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0); public_fuzz(k1); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz RSA sig"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, "ssh-rsa"); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz RSA SHA256 sig"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, "rsa-sha2-256"); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz RSA SHA512 sig"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, "rsa-sha2-512"); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz DSA sig"); buf = load_file("dsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA sig"); buf = load_file("ecdsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); #endif TEST_START("fuzz Ed25519 sig"); buf = load_file("ed25519_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); /* XXX fuzz decoded new-format blobs too */ } openssh-7.2p2/regress/unittests/sshkey/test_sshkey.c010064400017500001750000000357541267006270000212230ustar00djmdjm/* $OpenBSD: test_sshkey.c,v 1.9 2015/12/07 02:20:46 djm Exp $ */ /* * Regress test for sshkey.h key management API * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) # include #endif #include "../test_helper/test_helper.h" #include "ssherr.h" #include "sshbuf.h" #define SSHBUF_INTERNAL 1 /* access internals for testing */ #include "sshkey.h" #include "authfile.h" #include "common.h" #include "ssh2.h" void sshkey_tests(void); static void put_opt(struct sshbuf *b, const char *name, const char *value) { struct sshbuf *sect; sect = sshbuf_new(); ASSERT_PTR_NE(sect, NULL); ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0); if (value != NULL) ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0); ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0); sshbuf_free(sect); } static void build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, const struct sshkey *sign_key, const struct sshkey *ca_key, const char *sig_alg) { struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; u_char *sigblob; size_t siglen; ca_buf = sshbuf_new(); ASSERT_PTR_NE(ca_buf, NULL); ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); /* * Get the public key serialisation by rendering the key and skipping * the type string. This is a bit of a hack :/ */ pk = sshbuf_new(); ASSERT_PTR_NE(pk, NULL); ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0); ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); principals = sshbuf_new(); ASSERT_PTR_NE(principals, NULL); ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); critopts = sshbuf_new(); ASSERT_PTR_NE(critopts, NULL); put_opt(critopts, "force-command", "/usr/local/bin/nethack"); put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1"); exts = sshbuf_new(); ASSERT_PTR_NE(exts, NULL); put_opt(critopts, "permit-X11-forwarding", NULL); ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */ ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */ ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */ ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */ ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */ ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */ ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */ ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */ ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */ ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, sshbuf_ptr(b), sshbuf_len(b), sig_alg, 0), 0); ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ free(sigblob); sshbuf_free(ca_buf); sshbuf_free(exts); sshbuf_free(critopts); sshbuf_free(principals); sshbuf_free(pk); } static void signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, const u_char *d, size_t l) { size_t len; u_char *sig; ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 0), 0); ASSERT_SIZE_T_GT(len, 8); ASSERT_PTR_NE(sig, NULL); ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0); ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0); /* Fuzz test is more comprehensive, this is just a smoke test */ sig[len - 5] ^= 0x10; ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0); free(sig); } static void banana(u_char *s, size_t l) { size_t o; const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' }; for (o = 0; o < l; o += sizeof(the_banana)) { if (l - o < sizeof(the_banana)) { memcpy(s + o, "nanananana", l - o); break; } memcpy(s + o, banana, sizeof(the_banana)); } } static void signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg) { u_char i, buf[2049]; size_t lens[] = { 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129, 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049 }; for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) { test_subtest_info("%s key, banana length %zu", sshkey_type(k), lens[i]); banana(buf, lens[i]); signature_test(k, bad, sig_alg, buf, lens[i]); } } static struct sshkey * get_private(const char *n) { struct sshbuf *b; struct sshkey *ret; b = load_file(n); ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0); sshbuf_free(b); return ret; } void sshkey_tests(void) { struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; #ifdef OPENSSL_HAS_ECC struct sshkey *ke; #endif struct sshbuf *b; TEST_START("new invalid"); k1 = sshkey_new(-42); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("new/free KEY_UNSPEC"); k1 = sshkey_new(KEY_UNSPEC); ASSERT_PTR_NE(k1, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA1"); k1 = sshkey_new(KEY_RSA1); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA"); k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_DSA"); k1 = sshkey_new(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); #endif TEST_START("new/free KEY_ED25519"); k1 = sshkey_new(KEY_ED25519); ASSERT_PTR_NE(k1, NULL); /* These should be blank until key loaded or generated */ ASSERT_PTR_EQ(k1->ed25519_sk, NULL); ASSERT_PTR_EQ(k1->ed25519_pk, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_RSA"); k1 = sshkey_new_private(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_NE(k1->rsa->p, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_DSA"); k1 = sshkey_new_private(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_NE(k1->dsa->priv_key, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("generate KEY_RSA too small modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_RSA too large modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_DSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); #endif TEST_START("generate KEY_RSA"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr), SSH_ERR_INVALID_ARGUMENT); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr->rsa, NULL); ASSERT_PTR_NE(kr->rsa->n, NULL); ASSERT_PTR_NE(kr->rsa->e, NULL); ASSERT_PTR_NE(kr->rsa->p, NULL); ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); TEST_DONE(); TEST_START("generate KEY_DSA"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); ASSERT_PTR_NE(kd, NULL); ASSERT_PTR_NE(kd->dsa, NULL); ASSERT_PTR_NE(kd->dsa->g, NULL); ASSERT_PTR_NE(kd->dsa->priv_key, NULL); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_PTR_NE(ke, NULL); ASSERT_PTR_NE(ke->ecdsa, NULL); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); TEST_DONE(); #endif TEST_START("generate KEY_ED25519"); ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); ASSERT_PTR_NE(kf, NULL); ASSERT_INT_EQ(kf->type, KEY_ED25519); ASSERT_PTR_NE(kf->ed25519_pk, NULL); ASSERT_PTR_NE(kf->ed25519_sk, NULL); TEST_DONE(); TEST_START("demote KEY_RSA"); ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); TEST_DONE(); TEST_START("equal KEY_RSA/demoted KEY_RSA"); ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("demote KEY_DSA"); ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kd, k1); ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("demote KEY_ECDSA"); ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(ke, k1); ASSERT_INT_EQ(k1->type, KEY_ECDSA); ASSERT_PTR_NE(k1->ecdsa, NULL); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); TEST_DONE(); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); sshkey_free(k1); TEST_DONE(); #endif TEST_START("demote KEY_ED25519"); ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kf, k1); ASSERT_INT_EQ(k1->type, KEY_ED25519); ASSERT_PTR_NE(k1->ed25519_pk, NULL); ASSERT_PTR_EQ(k1->ed25519_sk, NULL); TEST_DONE(); TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("equal mismatched key types"); ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); #ifdef OPENSSL_HAS_ECC ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); #endif ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); TEST_DONE(); TEST_START("equal different keys"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); sshkey_free(k1); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); sshkey_free(k1); #ifdef OPENSSL_HAS_ECC ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); sshkey_free(k1); #endif ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); sshkey_free(k1); TEST_DONE(); sshkey_free(kr); sshkey_free(kd); #ifdef OPENSSL_HAS_ECC sshkey_free(ke); #endif sshkey_free(kf); TEST_START("certify key"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k1, NULL), 0); k2 = get_private("ed25519_2"); ASSERT_INT_EQ(sshkey_to_certified(k1), 0); ASSERT_PTR_NE(k1->cert, NULL); k1->cert->type = SSH2_CERT_TYPE_USER; k1->cert->serial = 1234; k1->cert->key_id = strdup("estragon"); ASSERT_PTR_NE(k1->cert->key_id, NULL); k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); ASSERT_PTR_NE(k1->cert->principals, NULL); k1->cert->principals[0] = strdup("estragon"); k1->cert->principals[1] = strdup("vladimir"); k1->cert->principals[2] = strdup("pozzo"); k1->cert->principals[3] = strdup("lucky"); ASSERT_PTR_NE(k1->cert->principals[0], NULL); ASSERT_PTR_NE(k1->cert->principals[1], NULL); ASSERT_PTR_NE(k1->cert->principals[2], NULL); ASSERT_PTR_NE(k1->cert->principals[3], NULL); k1->cert->valid_after = 0; k1->cert->valid_before = (u_int64_t)-1; k1->cert->critical = sshbuf_new(); ASSERT_PTR_NE(k1->cert->critical, NULL); k1->cert->extensions = sshbuf_new(); ASSERT_PTR_NE(k1->cert->extensions, NULL); put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); put_opt(k1->cert->critical, "source-address", "127.0.0.1"); put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); ASSERT_INT_EQ(sshkey_certify(k1, k2), 0); b = sshbuf_new(); ASSERT_PTR_NE(b, NULL); ASSERT_INT_EQ(sshkey_putb(k1, b), 0); ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); sshbuf_reset(b); TEST_DONE(); TEST_START("sign and verify RSA"); k1 = get_private("rsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, "ssh-rsa"); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); TEST_START("sign and verify RSA-SHA256"); k1 = get_private("rsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, "rsa-sha2-256"); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); TEST_START("sign and verify RSA-SHA512"); k1 = get_private("rsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, "rsa-sha2-512"); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); TEST_START("sign and verify DSA"); k1 = get_private("dsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("sign and verify ECDSA"); k1 = get_private("ecdsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); #endif TEST_START("sign and verify ED25519"); k1 = get_private("ed25519_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, NULL), 0); signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); TEST_START("nested certificate"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); k3 = get_private("rsa_1"); build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL); ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); ASSERT_PTR_EQ(k4, NULL); sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); sshbuf_free(b); TEST_DONE(); } openssh-7.2p2/regress/unittests/sshkey/testdata004075500017500001750000000000001267006270000202315ustar00djmdjmopenssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1010064400017500001750000000012401267006270000212140ustar00djmdjm-----BEGIN DSA PRIVATE KEY----- MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD /50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 KfXsZuBPuWe5FJz3ldaEgw== -----END DSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1-cert.fp010064400017500001750000000000631267006270000225550ustar00djmdjmSHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1-cert.pub010064400017500001750000000017361267006270000227460ustar00djmdjmssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgdTlbNU9Hn9Qng3FHxwH971bxCIoq1ern/QWFFDWXgmYAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAAAAAAAAYAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABAh/z1LIdNL1b66tQ8t9DY9BTB3BQKpTKmc7ezyFKLwl96yaIniZwD9Ticdbe/8i/Li3uCFE3EAt8NAIv9zff8Bg== DSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.fp010064400017500001750000000000631267006270000216220ustar00djmdjmSHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.fp.bb010064400017500001750000000001021267006270000221760ustar00djmdjmxetag-todiz-mifah-torec-mynyv-cyvit-gopon-pygag-rupic-cenav-bexax openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.param.g010064400017500001750000000004031267006270000225400ustar00djmdjm00eee5f505556d24a8cb996ae9c3adbe97fc525c0e6bafb30706e5a3882615dd51c17d725a403c910ed1ae109283c1dcea62069ca460291962ff72e06d27d9d286c525e86446d116b4de0f87c7d551e4bbe2241b23015078a9581c894d4d1a06b406dd8b79c7755f81064110735577ae3a98aa18cea33ff236c8332cd0f6e87add openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.param.priv010064400017500001750000000000511267006270000232710ustar00djmdjm5821b43929f5ec66e04fb967b9149cf795d68483 openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.param.pub010064400017500001750000000004031267006270000231000ustar00djmdjm00e757a727e6a1b10168ea9902ebe08f53f4ba18c6d8fdf551fbabbf6d8558f054dc0f6aae4c5b397c04d0bc2f8c2bebb1057f96b621273fed8b2b38d1579a86e956644e520073171887fde4b88b4a0697323928ee3a28b7e2caf3896d2f29b067840c9d88e765249c95fd54bb240c714b5bdf8f88d2ef58727ca1a7699216c42d openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1.pub010064400017500001750000000011351267006270000220040ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQt DSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_1_pw010064400017500001750000000014031267006270000217230ustar00djmdjm-----BEGIN DSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,BC8386C373B22EB7F00ADC821D5D8BE9 +HDV2DQ09sxrIAeXTz9r3YFuPRa2hk1+NGcr3ETkXbC6KiZ14wpTnGTloKwaQjIW eXTa9mpCOWAoohgvsVb+hOuOlP7AfeHu1IXV4EAS+GDpkiV5UxlCXXwqlD75Buu4 wwDd/p4SWzILH3WGjDk5JIXoxWNY13LHwC7Q6gtGJx4AicUG7YBRTXMIBDa/Kh77 6o2rFETKmp4VHBvHbakmiETfptdM8bbWxKWeY2vakThyESgeofsLoTOQCIwlEfJC s2D/KYL65C8VbHYgIoSLTQnooO45DDyxIuhCqP+H23mhv9vB1Od3nc2atgHj/XFs dcOPFkF/msDRYqxY3V0AS6+jpKwFodZ7g/hyGcyPxOkzlJVuKoKuH6P5PyQ69Gx0 iqri0xEPyABr7kGlXNrjjctojX+B4WwSnjg/2euXXWFXCRalIdA7ErATTiQbGOx7 Vd6Gn8PZbSy1MkqEDrZRip0pfAFJYI/8GXPC75BpnRsrVlfhtrngbW+kBP35LzaN l2K+RQ3gSB3iFoqNb1Kuu6T5MZlyVl5H2dVlJSeb1euQ2OycXdDoFTyJ4AiyWS7w Vlh8zeJnso5QRDjMwx99pZilbbuFGSLsahiGEveFc6o= -----END DSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_2010064400017500001750000000012401267006270000212150ustar00djmdjm-----BEGIN DSA PRIVATE KEY----- MIIBvQIBAAKBgQCbyPXNdHeLsjpobPVCMkfagBkt15Zsltqf/PGNP1y1cuz7rsTX ZekQwUkSTNm5coqXe+ZOw2O4tjobJDd60I1/VPgaB0NYlQR9Hn87M284WD4f6VY+ aunHmP134a8ybG5G4NqVNF3ihvxAR2pVITqb7kE46r2uYZNcNlHI8voRCwIVAMcP bwqFNsQbH5pJyZW30wj4KVZ3AoGBAIK98BVeKQVf8qDFqx9ovMuNgVSxpd+N0Yta 5ZEy1OI2ziu5RhjueIM2K7Gq2Mnp38ob1AM53BUxqlcBJaHEDa6rj6yvuMgW9oCJ dImBM8sIFxfBbXNbpJiMaDwa6WyT84OkpDE6uuAepTMnWOUWkUVkAiyokHDUGXkG GyoQblbXAoGBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0 FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk 0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZAhUAsY2f bDFNzgZ4DaZ9wLRzTgOswPU= -----END DSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_2.fp010064400017500001750000000000631267006270000216230ustar00djmdjmSHA256:ecwhWcXgpdBxZ2e+OjpRRY7dqXHHCD62BGtoVQQBwCk openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_2.fp.bb010064400017500001750000000001021267006270000221770ustar00djmdjmxeser-megad-pocan-rozit-belup-tapoh-fapif-kyvit-vonav-cehab-naxax openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_2.pub010064400017500001750000000011351267006270000220050ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAJvI9c10d4uyOmhs9UIyR9qAGS3XlmyW2p/88Y0/XLVy7PuuxNdl6RDBSRJM2blyipd75k7DY7i2OhskN3rQjX9U+BoHQ1iVBH0efzszbzhYPh/pVj5q6ceY/XfhrzJsbkbg2pU0XeKG/EBHalUhOpvuQTjqva5hk1w2Ucjy+hELAAAAFQDHD28KhTbEGx+aScmVt9MI+ClWdwAAAIEAgr3wFV4pBV/yoMWrH2i8y42BVLGl343Ri1rlkTLU4jbOK7lGGO54gzYrsarYyenfyhvUAzncFTGqVwElocQNrquPrK+4yBb2gIl0iYEzywgXF8Ftc1ukmIxoPBrpbJPzg6SkMTq64B6lMydY5RaRRWQCLKiQcNQZeQYbKhBuVtcAAACBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZ DSA test key #2 openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_n010064400017500001750000000012401267006270000213110ustar00djmdjm-----BEGIN DSA PRIVATE KEY----- MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD /50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 KfXsZuBPuWe5FJz3ldaEgw== -----END DSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/dsa_n_pw010064400017500001750000000026111267006270000220220ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCVs+LsMJ wnB5zM9U9pTXrGAAAAEAAAAAEAAAGzAAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0 uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y 4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0 k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw6 2+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl 6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/ I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84 ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAB4HiOcRW4w+sIqBL0 TPVbf0glN1hUi0rcE63Pqxmvxb8LkldC4IxAUagPrjhNAEW2AY42+CvPrtGB1z7gDADAIW xZX6wKwIcXP0Qh+xHE12F4u6mwfasssnAp4t1Ki8uCjMjnimgb3KdWpp0kiUV0oR062TXV PAdfrWjaq4fw0KOqbHIAG/v36AqzuqjSTfDbqvLZM3y0gp2Q1RxaQVJA5ZIKKyqRyFX7sr BaEIyCgeE3hM0EB7BycY1oIcS/eNxrACBWVJCENl5N7LtEYXNX7TANFniztfXzwaqGTT6A fCfbW4gz1UKldLUBzbIrPwMWlirAstbHvOf/2Iay2pNAs/SHhI0aF2jsGfvv5/D6N+r9dG B2SgDKBg7pywMH1DTvg6YT3P4GjCx0GUHqRCFLvD1rDdk4KSjvaRMpVq1PJ0/Wv6UGtsMS TR0PaEHDRNZqAX4YxqujnWrGKuRJhuz0eUvp7fZvbWHtiAMKV7368kkeUmkOHanb+TS+zs KINX8ev8zJZ6WVr8Vl+IQavpv0i2bXwS6QqbEuifpv/+uBb7pqRiU4u8en0eMdX1bZoTPM R6xHCnGD/Jpb3zS91Ya57T6CiXZ12KCaL6nWGnCkZVpzkfJ2HjFklWSWBQ6uyaosDQ== -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1010064400017500001750000000003431267006270000215270ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== -----END EC PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp010064400017500001750000000000631267006270000230650ustar00djmdjmSHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub010064400017500001750000000012201267006270000232420ustar00djmdjmecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgOtFRnMigkGliaYfPmX5IidVWfV3tRH6lqRXv0l8bvKoAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAAAAAAAABwAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2jAHwAAAAAE0eYHAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIHbxGwTnue7KxhHXGFvRcxBnekhQ3Qx84vV/Vs4oVCrpAAAAIQC7vk2+d14aS7td7kVXLQn392oALjEBzMZoDvT1vT/zOA== ECDSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.fp010064400017500001750000000000631267006270000221320ustar00djmdjmSHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb010064400017500001750000000001021267006270000225060ustar00djmdjmxibah-vocun-sogyn-byhen-rivem-hegyh-luneh-dozyr-vatyf-dufid-myxyx openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.param.curve010064400017500001750000000000131267006270000237430ustar00djmdjmprime256v1 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2010064400017500001750000000005551267006270000215350ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIBqBtN7e6Essd3dlsgISViPCXXC0atlNkGtoMgSQdBTKVUfeJOi4lc RZaXJdXnqWUqI/KEsH8h8QN4YcB8ugmAcc+gBwYFK4EEACOhgYkDgYYABAHZ2VNy oDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/ 0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs 6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== -----END EC PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.param.priv010064400017500001750000000001031267006270000235770ustar00djmdjm00f3cdc940278ef16bf9e4ffeedfc8ca3b9041dfda2c589363dd8b07d8088f2acc openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.param.pub010064400017500001750000000002031267006270000234060ustar00djmdjm040c595b9643ab5bdc9d29586d33ef4063773db1a044ed21b7945c77f2705abe40030da23d8e1dff92f1bf26df6fa66db6ab0a249530860dfcc291790829a5a507 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1.pub010064400017500001750000000002631267006270000223150ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQc= ECDSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_1_pw010064400017500001750000000004721267006270000222400ustar00djmdjm-----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15 8QkFoZHQkj9a2mt032sp+WKaJ1fwteqWDd4RpAW9OzDgqzMx1QO43qJgBDTfhzjt M2Q8YfiGjfBEYpg4kCbacfcV68DEV4z6Ll7rIzzzO7OfWUNL++brD64vKx4z6f46 +sn4nbZTXilpkzi/nmPDVzrNmTSywA8T7Yf0QcBUxks= -----END EC PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.fp010064400017500001750000000000631267006270000221330ustar00djmdjmSHA256:ed8YniRHA6qCrErCRnzrWxPHxYuA62a+CAFYUVxJgaI openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb010064400017500001750000000001021267006270000225070ustar00djmdjmxufag-danul-putub-mokin-pugaz-covid-dofag-nihuz-sysab-genar-zaxyx openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.param.curve010064400017500001750000000000121267006270000237430ustar00djmdjmsecp521r1 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.param.priv010064400017500001750000000002051267006270000236030ustar00djmdjm01a81b4dedee84b2c777765b202125623c25d70b46ad94d906b683204907414ca5547de24e8b895c45969725d5e7a9652a23f284b07f21f1037861c07cba098071cf openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.param.pub010064400017500001750000000004131267006270000234120ustar00djmdjm0401d9d95372a0379d070aac77363e924369b5cf43aed4425663ba7142cb8feebdd4c848b6a56a4cc25b4c5948e0c9c083d3e819317fd0a98b25fcbcbd27df5c62aaab018a70536d7755c2a3eed0bbdb576f1ae89fd83a0e6bbbcbc8da2e48b17306709f02ece86980f6a646ba201f38657419ff7fbbdf2cafebe290e6b83b0e491434f0e6 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_2.pub010064400017500001750000000004171267006270000223170ustar00djmdjmecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHZ2VNyoDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== ECDSA test key #2 openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_n010064400017500001750000000003431267006270000216240ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== -----END EC PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ecdsa_n_pw010064400017500001750000000010311267006270000223250ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABC4UwEov5 z0RrCm7AMCxbuiAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz dHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvy bfb6ZttqsKJJUwhg38wpF5CCmlpQcAAACgbCnAklQTHrf5qiHiMxKYwQJ7k/X9mp4fXD4v xUbgNZiXSxN26mn8mC2rH+WA6Lk3CexR/hrtLI2ndpBsYu1h6HhVkOwwm3Kd/PMKArCupW l6sYEabrT0EghXR/3aDEZvj79hgKSdu3RpayLvMdbCR8k1cg0/mDmR9hicWfeJ61n/IH05 tUR268+0BVRW9kDhh/cuv8tVY4L09jCCQ6CpsA== -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1010064400017500001750000000006331267006270000214500ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAJjnj4Ao54+A KAAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQ AAAED3KgoDbjR54V7bdNpfKlQY5m20UK1QaHytkCR+6rZEDFOG6kY7Rf4UtCFvPwKgo/Bz tXck2xC4a2WyA34XtIwZAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1-cert.fp010064400017500001750000000000631267006270000230040ustar00djmdjmSHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1-cert.pub010064400017500001750000000007461267006270000231750ustar00djmdjmssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIIxzuxl4z3uwAIslne8Huft+1n1IhHAlNbWZkQyyECCGAAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZAAAAAAAAAAgAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABABGTn+Bmz86Ajk+iqKCSdP5NClsYzn4alJd0V5bizhP0Kumc/HbqQfSt684J1WdSzih+EjvnTgBhK9jTBKb90AQ== ED25519 test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1.fp010064400017500001750000000000631267006270000220510ustar00djmdjmSHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1.fp.bb010064400017500001750000000001021267006270000224250ustar00djmdjmxubop-rekyd-bakal-nubuf-pahaf-gicuh-logeb-gocif-petod-galip-fuxux openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1.pub010064400017500001750000000001451267006270000222330ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZ ED25519 test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_1_pw010064400017500001750000000007201267006270000221530ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCus+kaow AUjHphacvRp98dAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFv PwKgo/BztXck2xC4a2WyA34XtIwZAAAAoJaqqgiYQuElraJAmYOm7Tb4nJ3eI4oj9mQ52M /Yd+ION2Ur1v8BDewpDX+LHEYgKHo3Mlmcn2UyF+QJ+7xUCW7QCtk/4szrJzw74DlEl6mH T8PT/f/av7PpECBD/YD3NoDlB9OWm/Q4sHcxfBEKfTGD7s2Onn71HgrdEOPqd4Sj/IQigR drfjtXEMlD32k9n3dd2eS9x7AHWYaGFEMkOcY= -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_2010064400017500001750000000006331267006270000214510ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCwAAAJix1mBGsdZg RgAAAAtzc2gtZWQyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCw AAAECZEQHXs18o3DKjhUYaTyt+bUbhqfMeqmsKjYyFvzGVgs9UrIuebd5kTSWbQh8zdTL0 Cx0ZIG2jNygK3bVuVgELAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_2.fp010064400017500001750000000000631267006270000220520ustar00djmdjmSHA256:vMbaARqVciRgXyZPNHDo+P5p5WK5yWG1Oo6VC35Bomw openssh-7.2p2/regress/unittests/sshkey/testdata/pw010064400017500001750000000000171267006270000206540ustar00djmdjmmekmitasdigoat openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_2.fp.bb010064400017500001750000000001021267006270000224260ustar00djmdjmxuces-bapyb-vikob-zesyv-budod-nupip-kebon-tacyc-fofed-lezic-soxax openssh-7.2p2/regress/unittests/sshkey/testdata/ed25519_2.pub010064400017500001750000000001451267006270000222340ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM9UrIuebd5kTSWbQh8zdTL0Cx0ZIG2jNygK3bVuVgEL ED25519 test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_1010064400017500001750000000010251267006270000213140ustar00djmdjmSSH PRIVATE KEY FILE FORMAT 1.1 ÎŒ§zUnºˆš†lJdxST¨…M41ú 5#¦_™‘_„3ÑœAg}0|ã˜e¸>qrÒÁØx3<˜8ÖäF! \×\þ§Ê!S‹òô?*ôœ¬îQ².;ÜÅè{YÌi|iB§~ñ;ýû$0w·'4 §  kˆg)RSA1 test key #1é©é©þ.;C]YtbJS2Ü ÄçúêÎ3Øÿ£Õ lu“ï0dÂ*<$À¦Ï1cÀ°„rø+YßV—6騦>lg5eÍ’UÏLu>0 ±‘¼c•ôçÆ&‡ôâ„®B¨IÃa½RP…HÀn•ÿ_oÑÙqq`gKfêS€Õ@ÑTþ)±íùþ•à@ O;nzvj=²qrÒÁØx3<˜8ÖäF! \×\þ§Ê!S‹òô?*ôœ¬îQ².;ÜÅè{YÌi|iB§~ñ;ýû$0w·'4 §  kˆg)RSA1 test key #1qÞ­miÏ&Ëü¢: ;÷CÓž_ÞrØHNÜìPUŸt¢‹›Ò¡š»zTKŽ‘88‹Ù|âžx#i´ŒÙ§]Ó_é´v.½ûyÅ8'-¡ß üx@ܶûÝÀ£‡š“Ñäú"5Ë·=rñ[Æpk’"XÝÆœjNpƒ{mìdŒÈ`UW8<󔉹®ÔJ(ȂМyæ} `îNUò1ÖØ(÷ZË4¾™ÐÁáž'JpôÖÜ¢–ñ×€«ÎtT iª#éÓzI˜¡Dßaopenssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_2010064400017500001750000000017251267006270000213240ustar00djmdjmSSH PRIVATE KEY FILE FORMAT 1.1 ʰ‘µzG@Á»p ôj!¡Äd}²ª±º½0ʾ$79h7k£^HÆ$¸êöµ”$ÔÁ¨HÉýõÍÇÁ·õåß#·­Q;y†ÓŒRýúãVVež†I²¿‹í÷É–däU4{ÑÅÜ=áÚýòÓJЇYQª=P 6ÐØ»ÌÞñZ³£Ý@½õ`e©9~õvÊÿ¶¾‚2öàaJê—›•„)fsú»½Ÿ2I\BˆB¢«hÝBO¶ýÎî«‘&ÊÍüƒO ºs­ƒ`уº…»eU\Æ¥6ëß„À!®(¢Ø³F_‹Xï@E®¡Ä­‹ö9WMk*ö{N³RSA1 test key #2é¡é¡‹EG^'"¨S-§PW.q®Ç [»-/ *ÚZŒ8æu‹ ×NF6ÅGÈ©i\A)íâbÎaâGvM,FüÖa»v­ á+LÙz_ý·ŒNyqõÇá/÷è¢;_k`±À¾ªÿ2’||Ù åúÇ•ʯ2YyG`¹oó*·—äí¥$å îq}LòTWŸ3÷§íÔYšÎ—ù q°ÃAD¤gàþ¥Ï,Ý»/éI ÚõǤmºÏµò‡r ^¯÷^ˆß“=+Ò!ZA÷[a»µv`ú7þ˜¼ÙË‘'3M6ÝÝ~E½F(€¬9º€àòP [G6fa·« /+Ë\xè\Ã@ ‚xûÎK~a w=!B§½´ˆ=”ïYÆïñp(s*Nå“ÖðuÍÿ(püÖ„·V:¡÷ø­¿å¹"×Mm.Å…Žð|?—аa[\M:Ž›N‰]¯O»…V.² YâgJËOMÔA÷#B®"iÑÆ=ÄiÊô+H,ôÛnŸ8Ú ‹ðð1žHkƒh;.ÎÍ…ÔÎ-"%Ɇ¤±ª‹GH oZú[6I™…ùÓþ¨¬OCÊÉ¢î½E²­$¡Û–êµú+<ž„$ß’ÝzÇÊE?Þ{U>‚먔¨+u}çM©ŠD%¸ çÃy÷ZЉ5CÙQ¹ˆO롼CÇ·!?DôÝ'×êÖâzñ¾PìRq]çòÑ%äÔ{pæMRŽÒ(µœÀû*ÆÎ„’ +>'ÉJˆpz•o,Gm™\ï7ØÒøA$r¥„¹h€®¿[½õâh÷Ýͪ=>é~Œ‹openssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_2.fp010064400017500001750000000000631267006270000217220ustar00djmdjmSHA256:JaOeRCnLl/TLe7vn1+aQ4ONyKZCUhK5x3k4VHilmbpE openssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_2.fp.bb010064400017500001750000000001021267006270000222760ustar00djmdjmxipag-zohut-zepuk-pisyv-kamog-pupus-netud-tudis-melup-cynov-gaxox openssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_2.param.n010064400017500001750000000010031267006270000226440ustar00djmdjm00cab091b57a154740c1bb7020f46a21a19dc40f647db2aab1babd30cabe241f0437391e68376ba35e48c624b8eaf6b59424d4c1a848c9fd1ef5cdc7c1b7f5e5df23b7ad513b79021286d38c52fdfae35656659e8649b2bf8bedf7c99664e45534007bd1c5dc3de1dafdf2d34ad087155951aa0f3d500b36d0d804bbccdef15ab31ca3dd40bdf5196065a97f397ef576caffb606be8232f6e0614aea0e979b9584296673fabb1dbd9f3212495c428842a2ab1f1768dd424fb6fdceeeab9126cacdfc834f0a0d09ba73ad8360d183ba85bb1565555cc6a536eb8d06df1a1e841107c021ae28a2d8b3465f9d8b58ef4045aea1c4ad7f8bf639574d6b142af67b4eb3 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa1_2.pub010064400017500001750000000012061267006270000221030ustar00djmdjm2048 65537 25587207108642486834576012232250034427766229965612147538722032399009467293691448851087324679403117563681753304072089087252850866332601294130674473984011813227791089686736237645788471744456489819306046398653719249100878753563464696688916667605969658659855996383142110932332560049231682024775766802333675397528993897914717996946881193454997890776063024953924432026083898531677702536941151535135950834711001926404724453460085864892836473957600610133803037286539329764689125111700732309717375455919436557475211197800228646235077584780367991159670572954337165006813357814232200750568307753718414790655085790471723847208627 RSA1 test key #2 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1010064400017500001750000000015671267006270000212460ustar00djmdjm-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18u d6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKd NSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wIDAQAB AoGAXyj5mpjmbD+YlxGIWz/zrM4hGsWgd4VteKEJxT6MMI4uzCRpkMd0ck8oHiwZ GAI/SwUzIsgtONQuH3AXVsUgghW4Ynn+8ksEv0IZ918WDMDwqvqkyrVzsOsZzqYj Pf8DUDKCpwFjnlknJ04yvWBZvVhWtY4OiZ8GV0Ttsu3k+GECQQD1YHfvBb5FdJBv Uhde2Il+jaFia8mwVVNNaiD2ECxXx6CzGz54ZLEB9NPVfDUZK8lJ4UJDqelWNh3i PF3RefWDAkEA1CVBzAFL4mNwpleVPzrfy69xP3gWOa26MxM/GE6zx9jC7HgQ3KPa WKdG/FuHs085aTRDaDLmGcZ8IvMuu7NgKQJAcIOKmxR0Gd8IN7NZugjqixggb0Pj mLKXXwESGiJyYtHL0zTj4Uqyi6Ya2GJ66o7UXscmnmYz828fJtTtZBdbRwJBALfi C2QvA32Zv/0PEXibKXy996WSC4G3ShwXZKtHHKHvCxY5BDSbehk59VesZrVPyG2e NYdOBxD0cIlCzJE56/ECQAndVkxvO8hwyEFGGwF3faHIAe/OxVb+MjaU25//Pe1/ h/e6tlCk4w9CODpyV685gV394eYwMcGDcIkipTNUDZs= -----END RSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1-cert.fp010064400017500001750000000000631267006270000225730ustar00djmdjmSHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1-cert.pub010064400017500001750000000011421267006270000227530ustar00djmdjmssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg98LhS2EHxLOWCLopZPwHdg/RJXusnkOqQXSc9R7aITkAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wAAAAAAAAAFAAAAAgAAAAZqdWxpdXMAAAASAAAABWhvc3QxAAAABWhvc3QyAAAAADaMAfAAAAAATR5gcAAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgU4bqRjtF/hS0IW8/AqCj8HO1dyTbELhrZbIDfhe0jBkAAABTAAAAC3NzaC1lZDI1NTE5AAAAQI3QGlUCzC07KorupxpDkkGy6tniaZ8EvBflzvv+itXWNchGvfUeHmVT6aX0sRqehdz/lR+GmXRoZBhofwh0qAM= RSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.fp010064400017500001750000000000631267006270000216400ustar00djmdjmSHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.fp.bb010064400017500001750000000001021267006270000222140ustar00djmdjmxosis-fodod-votot-dibum-ryvac-rediz-naruf-votun-kevis-halis-gexux openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.param.n010064400017500001750000000004031267006270000225650ustar00djmdjm00cb5799544edec5ac00ec781fc21a1119ce9a288e3116e72f3e78fbcba6998adcc98c235f2e77abf1ce92b76f064b624552c9f2582341e622e1a176eef232b5bac1bf3881babc0b7d57a1ef4439170852e192bc329d3523354a39610eab916e50c507c913a2a5f2c7596aad779c5f297121438bd2313ebb4ad4d7debba43271fb openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.param.p010064400017500001750000000002031267006270000225650ustar00djmdjm00f56077ef05be4574906f52175ed8897e8da1626bc9b055534d6a20f6102c57c7a0b31b3e7864b101f4d3d57c35192bc949e14243a9e956361de23c5dd179f583 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.param.q010064400017500001750000000002031267006270000225660ustar00djmdjm00d42541cc014be26370a657953f3adfcbaf713f781639adba33133f184eb3c7d8c2ec7810dca3da58a746fc5b87b34f396934436832e619c67c22f32ebbb36029 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1.pub010064400017500001750000000003451267006270000220240ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+w== RSA test key #1 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_1_pw010064400017500001750000000017321267006270000217460ustar00djmdjm-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,0C3F819F6EEA66A471BAEEDDA8171606 AhQNxgw7Z2un3dpm6KPHF1u5qVvOczm0yiTyPK4U11B3TTRhXOHdzPLAcKMX71Xq fmLm2/JIZATUbLTaysLKIQlmAgtpmXoKLv9b90R3AXLophgToZzOLpvlQTCt+y9G 0E3QQZG/LFy9BLNyw6uD5cy0RHT3FQb5VQDwfBvR/I+K3qWBFLlb7Rw9bCujYczu D3bimcDj/k6YkrWVsEa81Ch5RF2RClOYufti6bsvc4xIsB0Kd++vokER+kXFuQqf Tl0Jz+SG0kr9QtjVvkhBtSxzJ6/olAosoUySQ5hqsB8iECufBgp1KelXqsHFJQXy gCvVmGiivFUinX0rKOuWCHTplsSKQ9BnPSwDAAs8A7ZLcTXcLs/hMQ5r6fmOYfNN YthhjZyE2ciJO0lydGJUJMb5aJUak0rl+uINRlYCHTRLVwmCOmpfqz9SfcJb1ieU 4Us8NR+pXJar4U0+C2wVlNJkAdpL6GvYxN6vp7vLa+BiFwIZOQozswacIZk/ScXm QL9rmWug51RCmDeenX46WTEZeB0o0+xi60sDEDhhe4+iNYcJu5L0BJ5lqRFe3I5n HRRv1mBEjbF2fDcg/ChYfOXsc4gDivH2nObabeASuMFZyadmXfA8tnXRZf+7Wuy/ LZGYbM2xLeEyV3ss16WBHuIqexDt04OEZvs0jN90zj6Yv7qKCB975bdOcuKkN2Nn n9lA11R2pgsCs6COp9rYiWXkXZeDf3sW6kdcEV+/SzkVsv4JlHcsIzgk4WGVF/E/ ZkU4J9AvSdJPzEQDM+yszp0eeUow4+SAgpuNTqZiUO/2UUVbsr3qvlYMoCixhFAN -----END RSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2010064400017500001750000000032171267006270000212410ustar00djmdjm-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA9NEUXp78SAkmL4+eAj4mBzPOjk+ccCPVzkTR+mZJdyTwkJAB HUN4cn4a2kTmh7Er+N8CXCsiqxIOV1GfH2fwaCiBlOEXeQJi/cMjxr9kVWO4FhC6 l1UqbvPUdrUCUZjFTA9/Ah9MKgk7qGYq5SjE3p+sn4GLhRKbqmq9LjiHgMmkBuv/ a1Slit+rXHzO2F8fH5hkjeHivyYVgw45aNvGCe2RRfbpoeW2mRtgIv7y9wSewt6a mhEDXSo/F6mkqA7xVinzro5NettEXLo91tA9Hb6f6x/Mc/GJDNXTKhpWCGeJ6xeW nAefDZORWAY7Y9YbuAxhEJVi9QL5NWoFOA0C6wIDAQABAoIBAQDtRGVVfwhKWHOl zK76xXjdqhwaWJXpKRHiI1jOMawpyKdNtAMgdW+apxUnTXePMurG/HuxEC09VvaH MhfhvD6G9BsCS1UQdnuyLRnTWVLIXyjeWcA9QtEpTy8vDSb+Je2xVaNmTybl5qTn BH22Mtj6Wg5XWJn7kplDhMdssGTDLsSCMw/rcxe9iT2qOKyltQal23RHzR7SijGp QTtBp2SDGhvMZcyGuyMqJ084W8sdJpbyVzdDim2iaZdHlk7uvW2n0HcJ56I6yhIq 2U8wfgEEwydGVGHgmQNJ/n+SiT/hv6g5ebhDS46X9F9m5CHDwhdr0DrhPBVSsdhl 1HeJ0+FhAoGBAPuC3uNHToiJis688juKlwc3SQ6ger5ffAg3yaNhEcpHkvOtdZlF /CfX94xazMov/YqFwkvpSSdKsX+PeXuaqnb1hPKNYX5t45U9RjB/ox7BIQj/2rPx Bfs99UFW9HKP4HsVmLu1xeJg1Pc9iylTK/xrnwfYiZ+H7IGVccizjnqHAoGBAPkv n1flAdxBzJH/O0rXoig2EtZsDRMPY51MGDdqVOW14ZOfTVlmu0OSnkSKQm2twfro TPDVb2TY3wTRutz8H9yOFW1c1Nz4YOyTb8FmJhE2FWAQ9t8QpwUlhn15if72dS/Y 22+vP+AYu7wfqGL7QVVEXho5hGjXi053iEvfXBl9AoGAeZISpo1LGphRLgkKlVky E1zXxWgwrGB/FYHRx1UeQkZCc+K+Wy4G6kNr9r3VC04TIafx+Lt0jrd+AIibUfG6 v/GBJ7TLEU+QmAycJskrUaxMiYsSbbPtDjoumDytv8pn2VbhEqqUUg44IqHu6DS5 qDNlFWfHbgNHgIN6EmcoUXUCgYEAi2G57X4pRjx/4wIy9jAbggaNDuctgQXQoIGZ 4hVWG49a+CnZKDKweKGgaZI0igjxQhmCQAwC3RP520Y9EbLtV38aOSv93QQJowrt Le6nSGVKG4whqrAz3EsbKUA8kiLldbgFNjl+ryjmidnjZEpKRxmQ0XZuu/4k6+Us ldQAPjkCgYBwjSm5eDUtK2eEPaBtbJykV05CTv5rn6CKC9L7ZBTkCcdU1hxeqe99 wb22decnNawGRP1a5cGwqKJPOfkgybJVkdr6aqQW8ClzdFSaenjzs+nVW+T9JTXf 9lFpIZg5kN/geld3B9B4C99riTM0jg9hbe2RQvpLRTrZbnWMA1XoRw== -----END RSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.fp010064400017500001750000000000631267006270000216410ustar00djmdjmSHA256:NoQh0XBUuYUSWqnzOzOBnfpgJTRWLMj7BlWAb8IbjeE openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.fp.bb010064400017500001750000000001021267006270000222150ustar00djmdjmxogit-gupof-mydon-hocep-zuval-feson-rarif-cefar-tobar-ryvap-kuxex openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.param.n010064400017500001750000000010031267006270000225630ustar00djmdjm00f4d1145e9efc4809262f8f9e023e260733ce8e4f9c7023d5ce44d1fa66497724f09090011d4378727e1ada44e687b12bf8df025c2b22ab120e57519f1f67f068288194e117790262fdc323c6bf645563b81610ba97552a6ef3d476b5025198c54c0f7f021f4c2a093ba8662ae528c4de9fac9f818b85129baa6abd2e388780c9a406ebff6b54a58adfab5c7cced85f1f1f98648de1e2bf2615830e3968dbc609ed9145f6e9a1e5b6991b6022fef2f7049ec2de9a9a11035d2a3f17a9a4a80ef15629f3ae8e4d7adb445cba3dd6d03d1dbe9feb1fcc73f1890cd5d32a1a56086789eb17969c079f0d939158063b63d61bb80c61109562f502f9356a05380d02eb openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.param.p010064400017500001750000000004031267006270000225700ustar00djmdjm00fb82dee3474e88898acebcf23b8a970737490ea07abe5f7c0837c9a36111ca4792f3ad759945fc27d7f78c5accca2ffd8a85c24be949274ab17f8f797b9aaa76f584f28d617e6de3953d46307fa31ec12108ffdab3f105fb3df54156f4728fe07b1598bbb5c5e260d4f73d8b29532bfc6b9f07d8899f87ec819571c8b38e7a87 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.param.q010064400017500001750000000004031267006270000225710ustar00djmdjm00f92f9f57e501dc41cc91ff3b4ad7a2283612d66c0d130f639d4c18376a54e5b5e1939f4d5966bb43929e448a426dadc1fae84cf0d56f64d8df04d1badcfc1fdc8e156d5cd4dcf860ec936fc166261136156010f6df10a70525867d7989fef6752fd8db6faf3fe018bbbc1fa862fb4155445e1a398468d78b4e77884bdf5c197d openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_2.pub010064400017500001750000000006151267006270000220250ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD00RRenvxICSYvj54CPiYHM86OT5xwI9XORNH6Zkl3JPCQkAEdQ3hyfhraROaHsSv43wJcKyKrEg5XUZ8fZ/BoKIGU4Rd5AmL9wyPGv2RVY7gWELqXVSpu89R2tQJRmMVMD38CH0wqCTuoZirlKMTen6yfgYuFEpuqar0uOIeAyaQG6/9rVKWK36tcfM7YXx8fmGSN4eK/JhWDDjlo28YJ7ZFF9umh5baZG2Ai/vL3BJ7C3pqaEQNdKj8XqaSoDvFWKfOujk1620Rcuj3W0D0dvp/rH8xz8YkM1dMqGlYIZ4nrF5acB58Nk5FYBjtj1hu4DGEQlWL1Avk1agU4DQLr RSA test key #2 openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_n010064400017500001750000000015671267006270000213430ustar00djmdjm-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18u d6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKd NSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wIDAQAB AoGAXyj5mpjmbD+YlxGIWz/zrM4hGsWgd4VteKEJxT6MMI4uzCRpkMd0ck8oHiwZ GAI/SwUzIsgtONQuH3AXVsUgghW4Ynn+8ksEv0IZ918WDMDwqvqkyrVzsOsZzqYj Pf8DUDKCpwFjnlknJ04yvWBZvVhWtY4OiZ8GV0Ttsu3k+GECQQD1YHfvBb5FdJBv Uhde2Il+jaFia8mwVVNNaiD2ECxXx6CzGz54ZLEB9NPVfDUZK8lJ4UJDqelWNh3i PF3RefWDAkEA1CVBzAFL4mNwpleVPzrfy69xP3gWOa26MxM/GE6zx9jC7HgQ3KPa WKdG/FuHs085aTRDaDLmGcZ8IvMuu7NgKQJAcIOKmxR0Gd8IN7NZugjqixggb0Pj mLKXXwESGiJyYtHL0zTj4Uqyi6Ya2GJ66o7UXscmnmYz828fJtTtZBdbRwJBALfi C2QvA32Zv/0PEXibKXy996WSC4G3ShwXZKtHHKHvCxY5BDSbehk59VesZrVPyG2e NYdOBxD0cIlCzJE56/ECQAndVkxvO8hwyEFGGwF3faHIAe/OxVb+MjaU25//Pe1/ h/e6tlCk4w9CODpyV685gV394eYwMcGDcIkipTNUDZs= -----END RSA PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/testdata/rsa_n_pw010064400017500001750000000020651267006270000220430ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAFw/Wg/V I5SAXWj/HJr9qeAAAAEAAAAAEAAACXAAAAB3NzaC1yc2EAAAADAQABAAAAgQDLV5lUTt7F rADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu 7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylx IUOL0jE+u0rU1967pDJx+wAAAgD1iSGiMlMJt2VH4kx5yr0wCJS+4UOmX0bxKO7UH5Jcul K5eaSe5ZoKE7hTYBaz0K5dRF/0fqLsvVZlE4quDjFLN6Hyavgn2W/QM7SUqBHgRMal9pgH LnxX6mFNWJ+4yb7f3bcbVIdgmMm3sT9Xjwaf5xgzNlR2mkUWtFwjyQh6FxUo5apNzqNBwO l2Q4xfmyZTp1s++pStQ/su6obXpxnE2Nx5G/D84ZL5iWl+njUy/MvJTazHRbiTSyihU+UA mUr5ZNuP3WUYY+h3KVlHpYHJYB7l3AMTKuPMFLhY9V7BJ+DuKPaqBgX4hvRzY0eVQiFr61 ovjWjvfu1ulx550JqdYCgH2PpP0E89OQne35Cxs9QPThfe8DKojC9YquYh9zmVTvr7kNiE Soluk/7oKpQIDaC+/SRk7AJ2e3Cbt1lXyGNn37PuqaaC/apaF/DOD6Yig9aClS7jOUrT96 56trFAYfHEIKbRCUSMCiM1+x6HOLYf5ROrGE9KxT3kUD9XMsMpTva+cPpHUpbGpXcYE10N MyYDz+V5M2/ZoIdEhscJNQ3UnhaZpeEaqcOyNyo90n3Dnaw/WpMDD/kNMGfm8daTaYInnQ QnwA2gwlYfpTAqxE71oXgOuGmtA0yqJB4778Xq26Pb+B7/mZZZe6n0FVmiNC+ZG37ZGOw/ iGL9e2Sxzw== -----END OPENSSH PRIVATE KEY----- openssh-7.2p2/regress/unittests/sshkey/tests.c010064400017500001750000000007151267006270000200050ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ #include "includes.h" #include #include "../test_helper/test_helper.h" void sshkey_tests(void); void sshkey_file_tests(void); void sshkey_fuzz_tests(void); void tests(void) { OpenSSL_add_all_algorithms(); ERR_load_CRYPTO_strings(); sshkey_tests(); sshkey_file_tests(); sshkey_fuzz_tests(); } openssh-7.2p2/regress/unittests/test_helper004075500017500001750000000000001267006270000174305ustar00djmdjmopenssh-7.2p2/regress/unittests/test_helper/Makefile010064400017500001750000000003771267006270000211530ustar00djmdjm# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $ LIB= test_helper SRCS= test_helper.c fuzz.c DEBUGLIBS= no NOPROFILE= yes NOPIC= yes # Hack to allow building with SUBDIR in ../../Makefile regress: all install: @echo -n .include openssh-7.2p2/regress/unittests/test_helper/fuzz.c010064400017500001750000000241761267006270000206600ustar00djmdjm/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Utility functions/framework for fuzz tests */ #include "includes.h" #include #include #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include #include #include "test_helper.h" #include "atomicio.h" /* #define FUZZ_DEBUG */ #ifdef FUZZ_DEBUG # define FUZZ_DBG(x) do { \ printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ printf x; \ printf("\n"); \ fflush(stdout); \ } while (0) #else # define FUZZ_DBG(x) #endif /* For brevity later */ typedef unsigned long long fuzz_ullong; /* For base-64 fuzzing */ static const char fuzz_b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; struct fuzz { /* Fuzz method currently in use */ int strategy; /* Fuzz methods remaining */ int strategies; /* Original seed data blob */ void *seed; size_t slen; /* Current working copy of seed with fuzz mutations applied */ u_char *fuzzed; /* Used by fuzz methods */ size_t o1, o2; }; static const char * fuzz_ntop(u_int n) { switch (n) { case 0: return "NONE"; case FUZZ_1_BIT_FLIP: return "FUZZ_1_BIT_FLIP"; case FUZZ_2_BIT_FLIP: return "FUZZ_2_BIT_FLIP"; case FUZZ_1_BYTE_FLIP: return "FUZZ_1_BYTE_FLIP"; case FUZZ_2_BYTE_FLIP: return "FUZZ_2_BYTE_FLIP"; case FUZZ_TRUNCATE_START: return "FUZZ_TRUNCATE_START"; case FUZZ_TRUNCATE_END: return "FUZZ_TRUNCATE_END"; case FUZZ_BASE64: return "FUZZ_BASE64"; default: abort(); } } static int fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) { if (fuzz == NULL) return -1; switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen * 8, fuzz->o1); return 0; case FUZZ_2_BIT_FLIP: snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n", fuzz_ntop(fuzz->strategy), (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, fuzz->o1, fuzz->o2); return 0; case FUZZ_1_BYTE_FLIP: snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); return 0; case FUZZ_2_BYTE_FLIP: snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n", fuzz_ntop(fuzz->strategy), (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, ((fuzz_ullong)fuzz->slen) * fuzz->slen, fuzz->o1, fuzz->o2); return 0; case FUZZ_TRUNCATE_START: snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); return 0; case FUZZ_TRUNCATE_END: snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); return 0; case FUZZ_BASE64: assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n", fuzz_ntop(fuzz->strategy), (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, fuzz->slen * (fuzz_ullong)64, fuzz->o1, fuzz_b64chars[fuzz->o2]); return 0; default: return -1; abort(); } } static void dump(u_char *p, size_t len) { size_t i, j; for (i = 0; i < len; i += 16) { fprintf(stderr, "%.4zd: ", i); for (j = i; j < i + 16; j++) { if (j < len) fprintf(stderr, "%02x ", p[j]); else fprintf(stderr, " "); } fprintf(stderr, " "); for (j = i; j < i + 16; j++) { if (j < len) { if (isascii(p[j]) && isprint(p[j])) fprintf(stderr, "%c", p[j]); else fprintf(stderr, "."); } } fprintf(stderr, "\n"); } } void fuzz_dump(struct fuzz *fuzz) { char buf[256]; if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) { fprintf(stderr, "%s: fuzz invalid\n", __func__); abort(); } fputs(buf, stderr); fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen); dump(fuzz->seed, fuzz->slen); fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz)); dump(fuzz_ptr(fuzz), fuzz_len(fuzz)); } #ifdef SIGINFO static struct fuzz *last_fuzz; static void siginfo(int unused __attribute__((__unused__))) { char buf[256]; test_info(buf, sizeof(buf)); atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); if (last_fuzz != NULL) { fuzz_fmt(last_fuzz, buf, sizeof(buf)); atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); } } #endif struct fuzz * fuzz_begin(u_int strategies, const void *p, size_t l) { struct fuzz *ret = calloc(sizeof(*ret), 1); assert(p != NULL); assert(ret != NULL); ret->seed = malloc(l); assert(ret->seed != NULL); memcpy(ret->seed, p, l); ret->slen = l; ret->strategies = strategies; assert(ret->slen < SIZE_MAX / 8); assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1))); FUZZ_DBG(("begin, ret = %p", ret)); fuzz_next(ret); #ifdef SIGINFO last_fuzz = ret; signal(SIGINFO, siginfo); #endif return ret; } void fuzz_cleanup(struct fuzz *fuzz) { FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); #ifdef SIGINFO last_fuzz = NULL; signal(SIGINFO, SIG_DFL); #endif assert(fuzz != NULL); assert(fuzz->seed != NULL); assert(fuzz->fuzzed != NULL); free(fuzz->seed); free(fuzz->fuzzed); free(fuzz); } static int fuzz_strategy_done(struct fuzz *fuzz) { FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen)); switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: return fuzz->o1 >= fuzz->slen * 8; case FUZZ_2_BIT_FLIP: return fuzz->o2 >= fuzz->slen * 8; case FUZZ_2_BYTE_FLIP: return fuzz->o2 >= fuzz->slen; case FUZZ_1_BYTE_FLIP: case FUZZ_TRUNCATE_START: case FUZZ_TRUNCATE_END: case FUZZ_BASE64: return fuzz->o1 >= fuzz->slen; default: abort(); } } void fuzz_next(struct fuzz *fuzz) { u_int i; FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, " "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy), (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen)); if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) { /* If we are just starting out, we need to allocate too */ if (fuzz->fuzzed == NULL) { FUZZ_DBG(("alloc")); fuzz->fuzzed = calloc(fuzz->slen, 1); } /* Pick next strategy */ FUZZ_DBG(("advance")); for (i = 1; i <= FUZZ_MAX; i <<= 1) { if ((fuzz->strategies & i) != 0) { fuzz->strategy = i; break; } } FUZZ_DBG(("selected = %u", fuzz->strategy)); if (fuzz->strategy == 0) { FUZZ_DBG(("done, no more strategies")); return; } fuzz->strategies &= ~(fuzz->strategy); fuzz->o1 = fuzz->o2 = 0; } assert(fuzz->fuzzed != NULL); switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: assert(fuzz->o1 / 8 < fuzz->slen); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8); fuzz->o1++; break; case FUZZ_2_BIT_FLIP: assert(fuzz->o1 / 8 < fuzz->slen); assert(fuzz->o2 / 8 < fuzz->slen); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8); fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8); fuzz->o1++; if (fuzz->o1 >= fuzz->slen * 8) { fuzz->o1 = 0; fuzz->o2++; } break; case FUZZ_1_BYTE_FLIP: assert(fuzz->o1 < fuzz->slen); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->fuzzed[fuzz->o1] ^= 0xff; fuzz->o1++; break; case FUZZ_2_BYTE_FLIP: assert(fuzz->o1 < fuzz->slen); assert(fuzz->o2 < fuzz->slen); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->fuzzed[fuzz->o1] ^= 0xff; fuzz->fuzzed[fuzz->o2] ^= 0xff; fuzz->o1++; if (fuzz->o1 >= fuzz->slen) { fuzz->o1 = 0; fuzz->o2++; } break; case FUZZ_TRUNCATE_START: case FUZZ_TRUNCATE_END: assert(fuzz->o1 < fuzz->slen); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->o1++; break; case FUZZ_BASE64: assert(fuzz->o1 < fuzz->slen); assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2]; fuzz->o2++; if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) { fuzz->o2 = 0; fuzz->o1++; } break; default: abort(); } FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, " "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy), (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen)); } int fuzz_matches_original(struct fuzz *fuzz) { if (fuzz_len(fuzz) != fuzz->slen) return 0; return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0; } int fuzz_done(struct fuzz *fuzz) { FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, (u_long)fuzz->strategies)); return fuzz_strategy_done(fuzz) && fuzz->strategies == 0; } size_t fuzz_len(struct fuzz *fuzz) { assert(fuzz->fuzzed != NULL); switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: case FUZZ_2_BIT_FLIP: case FUZZ_1_BYTE_FLIP: case FUZZ_2_BYTE_FLIP: case FUZZ_BASE64: return fuzz->slen; case FUZZ_TRUNCATE_START: case FUZZ_TRUNCATE_END: assert(fuzz->o1 <= fuzz->slen); return fuzz->slen - fuzz->o1; default: abort(); } } u_char * fuzz_ptr(struct fuzz *fuzz) { assert(fuzz->fuzzed != NULL); switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: case FUZZ_2_BIT_FLIP: case FUZZ_1_BYTE_FLIP: case FUZZ_2_BYTE_FLIP: case FUZZ_BASE64: return fuzz->fuzzed; case FUZZ_TRUNCATE_START: assert(fuzz->o1 <= fuzz->slen); return fuzz->fuzzed + fuzz->o1; case FUZZ_TRUNCATE_END: assert(fuzz->o1 <= fuzz->slen); return fuzz->fuzzed; default: abort(); } } openssh-7.2p2/regress/unittests/test_helper/test_helper.c010064400017500001750000000303371267006270000221740ustar00djmdjm/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Utility functions/framework for regress tests */ #include "includes.h" #include #include #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include #include #include #include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif #include "test_helper.h" #include "atomicio.h" #define TEST_CHECK_INT(r, pred) do { \ switch (pred) { \ case TEST_EQ: \ if (r == 0) \ return; \ break; \ case TEST_NE: \ if (r != 0) \ return; \ break; \ case TEST_LT: \ if (r < 0) \ return; \ break; \ case TEST_LE: \ if (r <= 0) \ return; \ break; \ case TEST_GT: \ if (r > 0) \ return; \ break; \ case TEST_GE: \ if (r >= 0) \ return; \ break; \ default: \ abort(); \ } \ } while (0) #define TEST_CHECK(x1, x2, pred) do { \ switch (pred) { \ case TEST_EQ: \ if (x1 == x2) \ return; \ break; \ case TEST_NE: \ if (x1 != x2) \ return; \ break; \ case TEST_LT: \ if (x1 < x2) \ return; \ break; \ case TEST_LE: \ if (x1 <= x2) \ return; \ break; \ case TEST_GT: \ if (x1 > x2) \ return; \ break; \ case TEST_GE: \ if (x1 >= x2) \ return; \ break; \ default: \ abort(); \ } \ } while (0) extern char *__progname; static int verbose_mode = 0; static int quiet_mode = 0; static char *active_test_name = NULL; static u_int test_number = 0; static test_onerror_func_t *test_onerror = NULL; static void *onerror_ctx = NULL; static const char *data_dir = NULL; static char subtest_info[512]; int main(int argc, char **argv) { int ch; /* Handle systems without __progname */ if (__progname == NULL) { __progname = strrchr(argv[0], '/'); if (__progname == NULL || __progname[1] == '\0') __progname = argv[0]; else __progname++; if ((__progname = strdup(__progname)) == NULL) { fprintf(stderr, "strdup failed\n"); exit(1); } } while ((ch = getopt(argc, argv, "vqd:")) != -1) { switch (ch) { case 'd': data_dir = optarg; break; case 'q': verbose_mode = 0; quiet_mode = 1; break; case 'v': verbose_mode = 1; quiet_mode = 0; break; default: fprintf(stderr, "Unrecognised command line option\n"); fprintf(stderr, "Usage: %s [-v]\n", __progname); exit(1); } } setvbuf(stdout, NULL, _IONBF, 0); if (!quiet_mode) printf("%s: ", __progname); if (verbose_mode) printf("\n"); tests(); if (!quiet_mode) printf(" %u tests ok\n", test_number); return 0; } const char * test_data_file(const char *name) { static char ret[PATH_MAX]; if (data_dir != NULL) snprintf(ret, sizeof(ret), "%s/%s", data_dir, name); else strlcpy(ret, name, sizeof(ret)); if (access(ret, F_OK) != 0) { fprintf(stderr, "Cannot access data file %s: %s\n", ret, strerror(errno)); exit(1); } return ret; } void test_info(char *s, size_t len) { snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number, active_test_name == NULL ? "" : active_test_name, *subtest_info != '\0' ? " - " : "", subtest_info); } #ifdef SIGINFO static void siginfo(int unused __attribute__((__unused__))) { char buf[256]; test_info(buf, sizeof(buf)); atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); } #endif void test_start(const char *n) { assert(active_test_name == NULL); assert((active_test_name = strdup(n)) != NULL); *subtest_info = '\0'; if (verbose_mode) printf("test %u - \"%s\": ", test_number, active_test_name); test_number++; #ifdef SIGINFO signal(SIGINFO, siginfo); #endif } void set_onerror_func(test_onerror_func_t *f, void *ctx) { test_onerror = f; onerror_ctx = ctx; } void test_done(void) { *subtest_info = '\0'; assert(active_test_name != NULL); free(active_test_name); active_test_name = NULL; if (verbose_mode) printf("OK\n"); else if (!quiet_mode) { printf("."); fflush(stdout); } } void test_subtest_info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap); va_end(ap); } void ssl_err_check(const char *file, int line) { long openssl_error = ERR_get_error(); if (openssl_error == 0) return; fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s", file, line, ERR_error_string(openssl_error, NULL)); abort(); } static const char * pred_name(enum test_predicate p) { switch (p) { case TEST_EQ: return "EQ"; case TEST_NE: return "NE"; case TEST_LT: return "LT"; case TEST_LE: return "LE"; case TEST_GT: return "GT"; case TEST_GE: return "GE"; default: return "UNKNOWN"; } } static void test_die(void) { if (test_onerror != NULL) test_onerror(onerror_ctx); abort(); } static void test_header(const char *file, int line, const char *a1, const char *a2, const char *name, enum test_predicate pred) { fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n", file, line, test_number, active_test_name, *subtest_info != '\0' ? " - " : "", subtest_info); fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", name, pred_name(pred), a1, a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); } void assert_bignum(const char *file, int line, const char *a1, const char *a2, const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred) { int r = BN_cmp(aa1, aa2); TEST_CHECK_INT(r, pred); test_header(file, line, a1, a2, "BIGNUM", pred); fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1)); fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2)); test_die(); } void assert_string(const char *file, int line, const char *a1, const char *a2, const char *aa1, const char *aa2, enum test_predicate pred) { int r; /* Verify pointers are not NULL */ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); r = strcmp(aa1, aa2); TEST_CHECK_INT(r, pred); test_header(file, line, a1, a2, "STRING", pred); fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); test_die(); } static char * tohex(const void *_s, size_t l) { u_int8_t *s = (u_int8_t *)_s; size_t i, j; const char *hex = "0123456789abcdef"; char *r = malloc((l * 2) + 1); assert(r != NULL); for (i = j = 0; i < l; i++) { r[j++] = hex[(s[i] >> 4) & 0xf]; r[j++] = hex[s[i] & 0xf]; } r[j] = '\0'; return r; } void assert_mem(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, size_t l, enum test_predicate pred) { int r; if (l == 0) return; /* If length is >0, then verify pointers are not NULL */ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); r = memcmp(aa1, aa2, l); TEST_CHECK_INT(r, pred); test_header(file, line, a1, a2, "STRING", pred); fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l); test_die(); } static int memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where) { size_t i; for (i = 0; i < l; i++) { if (s[i] != v) { *where = i; return 1; } } return 0; } void assert_mem_filled(const char *file, int line, const char *a1, const void *aa1, u_char v, size_t l, enum test_predicate pred) { size_t where = -1; int r; char tmp[64]; if (l == 0) return; /* If length is >0, then verify the pointer is not NULL */ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); r = memvalcmp(aa1, v, l, &where); TEST_CHECK_INT(r, pred); test_header(file, line, a1, NULL, "MEM_ZERO", pred); fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l); snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, ((u_char *)aa1)[where], v); test_die(); } void assert_int(const char *file, int line, const char *a1, const char *a2, int aa1, int aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "INT", pred); fprintf(stderr, "%12s = %d\n", a1, aa1); fprintf(stderr, "%12s = %d\n", a2, aa2); test_die(); } void assert_size_t(const char *file, int line, const char *a1, const char *a2, size_t aa1, size_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "SIZE_T", pred); fprintf(stderr, "%12s = %zu\n", a1, aa1); fprintf(stderr, "%12s = %zu\n", a2, aa2); test_die(); } void assert_u_int(const char *file, int line, const char *a1, const char *a2, u_int aa1, u_int aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U_INT", pred); fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); test_die(); } void assert_long_long(const char *file, int line, const char *a1, const char *a2, long long aa1, long long aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "LONG LONG", pred); fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); test_die(); } void assert_char(const char *file, int line, const char *a1, const char *a2, char aa1, char aa2, enum test_predicate pred) { char buf[8]; TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "CHAR", pred); fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); test_die(); } void assert_u8(const char *file, int line, const char *a1, const char *a2, u_int8_t aa1, u_int8_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U8", pred); fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); test_die(); } void assert_u16(const char *file, int line, const char *a1, const char *a2, u_int16_t aa1, u_int16_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U16", pred); fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); test_die(); } void assert_u32(const char *file, int line, const char *a1, const char *a2, u_int32_t aa1, u_int32_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U32", pred); fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); test_die(); } void assert_u64(const char *file, int line, const char *a1, const char *a2, u_int64_t aa1, u_int64_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U64", pred); fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, (unsigned long long)aa1, (unsigned long long)aa1); fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, (unsigned long long)aa2, (unsigned long long)aa2); test_die(); } void assert_ptr(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "PTR", pred); fprintf(stderr, "%12s = %p\n", a1, aa1); fprintf(stderr, "%12s = %p\n", a2, aa2); test_die(); } openssh-7.2p2/regress/unittests/test_helper/test_helper.h010064400017500001750000000310511267006270000221730ustar00djmdjm/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Utility functions/framework for regress tests */ #ifndef _TEST_HELPER_H #define _TEST_HELPER_H #include "includes.h" #include #ifdef HAVE_STDINT_H # include #endif #include #include enum test_predicate { TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE }; typedef void (test_onerror_func_t)(void *); /* Supplied by test suite */ void tests(void); const char *test_data_file(const char *name); void test_start(const char *n); void test_info(char *s, size_t len); void set_onerror_func(test_onerror_func_t *f, void *ctx); void test_done(void); void test_subtest_info(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void ssl_err_check(const char *file, int line); void assert_bignum(const char *file, int line, const char *a1, const char *a2, const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred); void assert_string(const char *file, int line, const char *a1, const char *a2, const char *aa1, const char *aa2, enum test_predicate pred); void assert_mem(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, size_t l, enum test_predicate pred); void assert_mem_filled(const char *file, int line, const char *a1, const void *aa1, u_char v, size_t l, enum test_predicate pred); void assert_int(const char *file, int line, const char *a1, const char *a2, int aa1, int aa2, enum test_predicate pred); void assert_size_t(const char *file, int line, const char *a1, const char *a2, size_t aa1, size_t aa2, enum test_predicate pred); void assert_u_int(const char *file, int line, const char *a1, const char *a2, u_int aa1, u_int aa2, enum test_predicate pred); void assert_long_long(const char *file, int line, const char *a1, const char *a2, long long aa1, long long aa2, enum test_predicate pred); void assert_char(const char *file, int line, const char *a1, const char *a2, char aa1, char aa2, enum test_predicate pred); void assert_ptr(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, enum test_predicate pred); void assert_u8(const char *file, int line, const char *a1, const char *a2, u_int8_t aa1, u_int8_t aa2, enum test_predicate pred); void assert_u16(const char *file, int line, const char *a1, const char *a2, u_int16_t aa1, u_int16_t aa2, enum test_predicate pred); void assert_u32(const char *file, int line, const char *a1, const char *a2, u_int32_t aa1, u_int32_t aa2, enum test_predicate pred); void assert_u64(const char *file, int line, const char *a1, const char *a2, u_int64_t aa1, u_int64_t aa2, enum test_predicate pred); #define TEST_START(n) test_start(n) #define TEST_DONE() test_done() #define TEST_ONERROR(f, c) set_onerror_func(f, c) #define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__) #define ASSERT_BIGNUM_EQ(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_STRING_EQ(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_MEM_EQ(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ) #define ASSERT_MEM_FILLED_EQ(a1, c, l) \ assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ) #define ASSERT_MEM_ZERO_EQ(a1, l) \ assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ) #define ASSERT_INT_EQ(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_SIZE_T_EQ(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_U_INT_EQ(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_LONG_LONG_EQ(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_CHAR_EQ(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_PTR_EQ(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_U8_EQ(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_U16_EQ(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_U32_EQ(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_U64_EQ(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) #define ASSERT_BIGNUM_NE(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_STRING_NE(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_MEM_NE(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE) #define ASSERT_MEM_ZERO_NE(a1, l) \ assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE) #define ASSERT_INT_NE(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_SIZE_T_NE(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_U_INT_NE(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_LONG_LONG_NE(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_CHAR_NE(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_PTR_NE(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_U8_NE(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_U16_NE(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_U32_NE(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_U64_NE(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) #define ASSERT_BIGNUM_LT(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_STRING_LT(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_MEM_LT(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT) #define ASSERT_INT_LT(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_SIZE_T_LT(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_U_INT_LT(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_LONG_LONG_LT(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_CHAR_LT(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_PTR_LT(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_U8_LT(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_U16_LT(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_U32_LT(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_U64_LT(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) #define ASSERT_BIGNUM_LE(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_STRING_LE(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_MEM_LE(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE) #define ASSERT_INT_LE(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_SIZE_T_LE(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_U_INT_LE(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_LONG_LONG_LE(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_CHAR_LE(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_PTR_LE(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_U8_LE(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_U16_LE(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_U32_LE(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_U64_LE(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) #define ASSERT_BIGNUM_GT(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_STRING_GT(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_MEM_GT(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT) #define ASSERT_INT_GT(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_SIZE_T_GT(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_U_INT_GT(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_LONG_LONG_GT(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_CHAR_GT(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_PTR_GT(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_U8_GT(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_U16_GT(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_U32_GT(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_U64_GT(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) #define ASSERT_BIGNUM_GE(a1, a2) \ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_STRING_GE(a1, a2) \ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_MEM_GE(a1, a2, l) \ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE) #define ASSERT_INT_GE(a1, a2) \ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_SIZE_T_GE(a1, a2) \ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_U_INT_GE(a1, a2) \ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_LONG_LONG_GE(a1, a2) \ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_CHAR_GE(a1, a2) \ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_PTR_GE(a1, a2) \ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_U8_GE(a1, a2) \ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_U16_GE(a1, a2) \ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_U32_GE(a1, a2) \ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) #define ASSERT_U64_GE(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) /* Fuzzing support */ struct fuzz; #define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */ #define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */ #define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */ #define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */ #define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */ #define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */ #define FUZZ_BASE64 0x00000040 /* Try all base64 chars */ #define FUZZ_MAX FUZZ_BASE64 /* Start fuzzing a blob of data with selected strategies (bitmask) */ struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l); /* Free a fuzz context */ void fuzz_cleanup(struct fuzz *fuzz); /* Prepare the next fuzz case in the series */ void fuzz_next(struct fuzz *fuzz); /* * Check whether this fuzz case is identical to the original * This is slow, but useful if the caller needs to ensure that all tests * generated change the input (e.g. when fuzzing signatures). */ int fuzz_matches_original(struct fuzz *fuzz); /* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ int fuzz_done(struct fuzz *fuzz); /* Return the length and a pointer to the current fuzzed case */ size_t fuzz_len(struct fuzz *fuzz); u_char *fuzz_ptr(struct fuzz *fuzz); /* Dump the current fuzz case to stderr */ void fuzz_dump(struct fuzz *fuzz); #endif /* _TEST_HELPER_H */ openssh-7.2p2/regress/valgrind-unit.sh010075500017500001750000000007611267006270000162520ustar00djmdjm#!/bin/sh UNIT_BINARY="$1" shift UNIT_ARGS="$@" test "x$OBJ" = "x" && OBJ=$PWD # This mostly replicates the logic in test-exec.sh for running the # regress tests under valgrind. VG_TEST=`basename $UNIT_BINARY` VG_LOG="$OBJ/valgrind-out/${VG_TEST}.%p" VG_OPTS="--track-origins=yes --leak-check=full --log-file=${VG_LOG}" VG_OPTS="$VG_OPTS --trace-children=yes" VG_PATH="valgrind" if [ "x$VALGRIND_PATH" != "x" ]; then VG_PATH="$VALGRIND_PATH" fi exec $VG_PATH $VG_OPTS $UNIT_BINARY $UNIT_ARGS openssh-7.2p2/regress/yes-head.sh010064400017500001750000000007031267006270000151570ustar00djmdjm# $OpenBSD: yes-head.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="yes pipe head" for p in ${SSH_PROTOCOLS}; do lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)` if [ $? -ne 0 ]; then fail "yes|head test failed" lines = 0; fi if [ $lines -ne 2000 ]; then fail "yes|head returns $lines lines instead of 2000" fi done openssh-7.2p2/rijndael.c010064400017500001750000001471121267006270000134140ustar00djmdjm/* $OpenBSD: rijndael.c,v 1.20 2015/03/16 11:09:52 djm Exp $ */ /** * rijndael-alg-fst.c * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen * @author Antoon Bosselaers * @author Paulo Barreto * * 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. */ #include "includes.h" #include #include #include "rijndael.h" #undef FULL_UNROLL /* Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; Te2[x] = S [x].[01, 03, 02, 01]; Te3[x] = S [x].[01, 01, 03, 02]; Td0[x] = Si[x].[0e, 09, 0d, 0b]; Td1[x] = Si[x].[0b, 0e, 09, 0d]; Td2[x] = Si[x].[0d, 0b, 0e, 09]; Td3[x] = Si[x].[09, 0d, 0b, 0e]; Td4[x] = Si[x].[01]; */ static const u32 Te0[256] = { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, }; static const u32 Te1[256] = { 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, }; static const u32 Te2[256] = { 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, }; static const u32 Te3[256] = { 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, }; #if 0 static const u32 Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, }; static const u32 Td1[256] = { 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, }; static const u32 Td2[256] = { 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, }; static const u32 Td3[256] = { 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, }; static const u8 Td4[256] = { 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, }; #endif static const u32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } /** * Expand the cipher key into the encryption key schedule. * * @return the number of rounds for the given cipher key size. */ int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { int i = 0; u32 temp; rk[0] = GETU32(cipherKey ); rk[1] = GETU32(cipherKey + 4); rk[2] = GETU32(cipherKey + 8); rk[3] = GETU32(cipherKey + 12); if (keyBits == 128) { for (;;) { temp = rk[3]; rk[4] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp ) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { return 10; } rk += 4; } } rk[4] = GETU32(cipherKey + 16); rk[5] = GETU32(cipherKey + 20); if (keyBits == 192) { for (;;) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp ) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) { return 12; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } } rk[6] = GETU32(cipherKey + 24); rk[7] = GETU32(cipherKey + 28); if (keyBits == 256) { for (;;) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp ) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) { return 14; } temp = rk[11]; rk[12] = rk[ 4] ^ (Te2[(temp >> 24) ] & 0xff000000) ^ (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(temp ) & 0xff] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } } return 0; } #if 0 /** * Expand the cipher key into the decryption key schedule. * * @return the number of rounds for the given cipher key size. */ int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { int Nr, i, j; u32 temp; /* expand the cipher key: */ Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); /* invert the order of the round keys: */ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } /* apply the inverse MixColumn transform to all round keys but the first and the last: */ for (i = 1; i < Nr; i++) { rk += 4; rk[0] = Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[0] ) & 0xff] & 0xff]; rk[1] = Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[1] ) & 0xff] & 0xff]; rk[2] = Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[2] ) & 0xff] & 0xff]; rk[3] = Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[3] ) & 0xff] & 0xff]; } return Nr; } #endif void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(pt ) ^ rk[0]; s1 = GETU32(pt + 4) ^ rk[1]; s2 = GETU32(pt + 8) ^ rk[2]; s3 = GETU32(pt + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; /* round 3: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; /* round 4: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; /* round 5: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; /* round 6: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; /* round 7: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; /* round 8: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; /* round 9: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; if (Nr > 10) { /* round 10: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; /* round 11: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; if (Nr > 12) { /* round 12: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; /* round 13: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ rk[4]; t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ rk[5]; t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ rk[6]; t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Te0[(t0 >> 24) ] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 ) & 0xff] ^ rk[0]; s1 = Te0[(t1 >> 24) ] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t0 ) & 0xff] ^ rk[1]; s2 = Te0[(t2 >> 24) ] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 ) & 0xff] ^ rk[2]; s3 = Te0[(t3 >> 24) ] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Te2[(t0 >> 24) ] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(ct , s0); s1 = (Te2[(t1 >> 24) ] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(ct + 4, s1); s2 = (Te2[(t2 >> 24) ] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(ct + 8, s2); s3 = (Te2[(t3 >> 24) ] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(ct + 12, s3); } #if 0 static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(ct ) ^ rk[0]; s1 = GETU32(ct + 4) ^ rk[1]; s2 = GETU32(ct + 8) ^ rk[2]; s3 = GETU32(ct + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; /* round 3: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; /* round 4: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; /* round 5: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; /* round 6: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; /* round 7: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; /* round 8: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; /* round 9: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; if (Nr > 10) { /* round 10: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; /* round 11: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; if (Nr > 12) { /* round 12: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; /* round 13: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ rk[4]; t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ rk[5]; t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ rk[6]; t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Td0[(t0 >> 24) ] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[(t1 ) & 0xff] ^ rk[0]; s1 = Td0[(t1 >> 24) ] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[(t2 ) & 0xff] ^ rk[1]; s2 = Td0[(t2 >> 24) ] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[(t3 ) & 0xff] ^ rk[2]; s3 = Td0[(t3 >> 24) ] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[(t0 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Td4[(t0 >> 24) ] << 24) ^ (Td4[(t3 >> 16) & 0xff] << 16) ^ (Td4[(t2 >> 8) & 0xff] << 8) ^ (Td4[(t1 ) & 0xff]) ^ rk[0]; PUTU32(pt , s0); s1 = (Td4[(t1 >> 24) ] << 24) ^ (Td4[(t0 >> 16) & 0xff] << 16) ^ (Td4[(t3 >> 8) & 0xff] << 8) ^ (Td4[(t2 ) & 0xff]) ^ rk[1]; PUTU32(pt + 4, s1); s2 = (Td4[(t2 >> 24) ] << 24) ^ (Td4[(t1 >> 16) & 0xff] << 16) ^ (Td4[(t0 >> 8) & 0xff] << 8) ^ (Td4[(t3 ) & 0xff]) ^ rk[2]; PUTU32(pt + 8, s2); s3 = (Td4[(t3 >> 24) ] << 24) ^ (Td4[(t2 >> 16) & 0xff] << 16) ^ (Td4[(t1 >> 8) & 0xff] << 8) ^ (Td4[(t0 ) & 0xff]) ^ rk[3]; PUTU32(pt + 12, s3); } #endif openssh-7.2p2/rijndael.h010064400017500001750000000041051267006270000134130ustar00djmdjm/* $OpenBSD: rijndael.h,v 1.14 2014/04/29 15:42:07 markus Exp $ */ /** * rijndael-alg-fst.h * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen * @author Antoon Bosselaers * @author Paulo Barreto * * 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. */ #ifndef _PRIVATE_RIJNDAEL_H #define _PRIVATE_RIJNDAEL_H #define AES_MAXKEYBITS (256) #define AES_MAXKEYBYTES (AES_MAXKEYBITS/8) /* for 256-bit keys, fewer for less */ #define AES_MAXROUNDS 14 typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int); void rijndaelEncrypt(const unsigned int [], int, const unsigned char [], unsigned char []); /* The structure for key information */ typedef struct { int decrypt; int Nr; /* key-length-dependent number of rounds */ u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */ } rijndael_ctx; void rijndael_set_key(rijndael_ctx *, u_char *, int, int); void rijndael_decrypt(rijndael_ctx *, u_char *, u_char *); void rijndael_encrypt(rijndael_ctx *, u_char *, u_char *); #endif /* _PRIVATE_RIJNDAEL_H */ openssh-7.2p2/roaming.h010064400017500001750000000000001267006270000132450ustar00djmdjmopenssh-7.2p2/rsa.c010064400017500001750000000120051267006270000124010ustar00djmdjm/* $OpenBSD: rsa.c,v 1.32 2014/06/24 01:13:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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. * * 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. * * * Description of the RSA algorithm can be found e.g. from the following * sources: * * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. * * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to * Computer Security. Prentice-Hall, 1989. * * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, * 1994. * * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications * System and Method. US Patent 4,405,829, 1983. * * Hans Riesel: Prime Numbers and Computer Methods for Factorization. * Birkhauser, 1994. * * The RSA Frequently Asked Questions document by RSA Data Security, * Inc., 1995. * * RSA in 3 lines of perl by Adam Back , 1995, as * included below: * * [gone - had to be deleted - what a pity] */ #include "includes.h" #include #include #include #include "rsa.h" #include "log.h" #include "ssherr.h" int rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) { u_char *inbuf = NULL, *outbuf = NULL; int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) return SSH_ERR_INVALID_ARGUMENT; olen = BN_num_bytes(key->n); if ((outbuf = malloc(olen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } ilen = BN_num_bytes(in); if ((inbuf = malloc(ilen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } BN_bn2bin(in, inbuf); if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, RSA_PKCS1_PADDING)) <= 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (BN_bin2bn(outbuf, len, out) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; out: if (outbuf != NULL) { explicit_bzero(outbuf, olen); free(outbuf); } if (inbuf != NULL) { explicit_bzero(inbuf, ilen); free(inbuf); } return r; } int rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) { u_char *inbuf = NULL, *outbuf = NULL; int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; olen = BN_num_bytes(key->n); if ((outbuf = malloc(olen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } ilen = BN_num_bytes(in); if ((inbuf = malloc(ilen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } BN_bn2bin(in, inbuf); if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, RSA_PKCS1_PADDING)) <= 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } else if (BN_bin2bn(outbuf, len, out) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; out: if (outbuf != NULL) { explicit_bzero(outbuf, olen); free(outbuf); } if (inbuf != NULL) { explicit_bzero(inbuf, ilen); free(inbuf); } return r; } /* calculate p-1 and q-1 */ int rsa_generate_additional_parameters(RSA *rsa) { BIGNUM *aux = NULL; BN_CTX *ctx = NULL; int r; if ((ctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((aux = BN_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || (BN_sub(aux, rsa->p, BN_value_one()) == 0) || (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; out: BN_clear_free(aux); BN_CTX_free(ctx); return r; } openssh-7.2p2/rsa.h010064400017500001750000000015401267006270000124100ustar00djmdjm/* $OpenBSD: rsa.h,v 1.17 2014/06/24 01:13:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * RSA key generation, encryption and decryption. * * 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 RSA_H #define RSA_H #include #include int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); int rsa_generate_additional_parameters(RSA *); #endif /* RSA_H */ openssh-7.2p2/sandbox-capsicum.c010064400017500001750000000065041267006270000150630ustar00djmdjm/* * Copyright (c) 2011 Dag-Erling Smorgrav * * 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" #ifdef SANDBOX_CAPSICUM #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "monitor.h" #include "ssh-sandbox.h" #include "xmalloc.h" /* * Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits, * limits rights on stdout, stdin, stderr, monitor and switches to * capability mode. */ struct ssh_sandbox { struct monitor *monitor; pid_t child_pid; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; /* * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ debug3("%s: preparing capsicum sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->monitor = monitor; box->child_pid = 0; return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { struct rlimit rl_zero; cap_rights_t rights; rl_zero.rlim_cur = rl_zero.rlim_max = 0; if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", __func__, strerror(errno)); #ifndef SANDBOX_SKIP_RLIMIT_NOFILE if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", __func__, strerror(errno)); #endif if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", __func__, strerror(errno)); cap_rights_init(&rights); if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) fatal("can't limit stdin: %m"); if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) fatal("can't limit stdout: %m"); if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) fatal("can't limit stderr: %m"); cap_rights_init(&rights, CAP_READ, CAP_WRITE); if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && errno != ENOSYS) fatal("%s: failed to limit the network socket", __func__); cap_rights_init(&rights, CAP_WRITE); if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && errno != ENOSYS) fatal("%s: failed to limit the logging socket", __func__); if (cap_enter() < 0 && errno != ENOSYS) fatal("%s: failed to enter capability mode", __func__); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { box->child_pid = child_pid; } #endif /* SANDBOX_CAPSICUM */ openssh-7.2p2/sandbox-darwin.c010064400017500001750000000047411267006270000145440ustar00djmdjm/* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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" #ifdef SANDBOX_DARWIN #include #include #include #include #include #include #include #include #include "log.h" #include "sandbox.h" #include "xmalloc.h" /* Darwin/OS X sandbox */ struct ssh_sandbox { pid_t child_pid; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; /* * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ debug3("%s: preparing Darwin sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->child_pid = 0; return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { char *errmsg; struct rlimit rl_zero; debug3("%s: starting Darwin sandbox", __func__); if (sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, &errmsg) == -1) fatal("%s: sandbox_init: %s", __func__, errmsg); /* * The kSBXProfilePureComputation still allows sockets, so * we must disable these using rlimit. */ rl_zero.rlim_cur = rl_zero.rlim_max = 0; if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", __func__, strerror(errno)); if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", __func__, strerror(errno)); if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", __func__, strerror(errno)); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { box->child_pid = child_pid; } #endif /* SANDBOX_DARWIN */ openssh-7.2p2/sandbox-null.c010064400017500001750000000031721267006270000142270ustar00djmdjm/* $OpenBSD$ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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" #ifdef SANDBOX_NULL #include #include #include #include #include #include #include #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" /* dummy sandbox */ struct ssh_sandbox { int junk; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; /* * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ box = xcalloc(1, sizeof(*box)); return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { /* Nothing to do here */ } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { /* Nothing to do here */ } #endif /* SANDBOX_NULL */ openssh-7.2p2/sandbox-pledge.c010064400017500001750000000035231267006270000145150ustar00djmdjm/* $OpenBSD: sandbox-pledge.c,v 1.1 2015/10/09 01:37:08 deraadt Exp $ */ /* * Copyright (c) 2015 Theo de Raadt * * 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" #ifdef SANDBOX_PLEDGE #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" struct ssh_sandbox { pid_t child_pid; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *m) { struct ssh_sandbox *box; debug3("%s: preparing pledge sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->child_pid = 0; return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { if (pledge("stdio", NULL) == -1) fatal("%s: pledge()", __func__); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { box->child_pid = child_pid; /* Nothing to do here */ } #endif /* SANDBOX_PLEDGE */ openssh-7.2p2/sandbox-rlimit.c010064400017500001750000000047121267006270000145560ustar00djmdjm/* $OpenBSD: sandbox-rlimit.c,v 1.3 2011/06/23 09:34:13 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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" #ifdef SANDBOX_RLIMIT #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */ struct ssh_sandbox { pid_t child_pid; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; /* * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ debug3("%s: preparing rlimit sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->child_pid = 0; return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { struct rlimit rl_zero; rl_zero.rlim_cur = rl_zero.rlim_max = 0; #ifndef SANDBOX_SKIP_RLIMIT_FSIZE if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", __func__, strerror(errno)); #endif #ifndef SANDBOX_SKIP_RLIMIT_NOFILE if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", __func__, strerror(errno)); #endif #ifdef HAVE_RLIMIT_NPROC if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", __func__, strerror(errno)); #endif } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { box->child_pid = child_pid; } #endif /* SANDBOX_RLIMIT */ openssh-7.2p2/sandbox-seccomp-filter.c010064400017500001750000000202561267006270000161730ustar00djmdjm/* * Copyright (c) 2012 Will Drewry * * 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. */ /* * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose * filter breakage during development. *Do not* use this in production, * as it relies on making library calls that are unsafe in signal context. * * Instead, live systems the auditctl(8) may be used to monitor failures. * E.g. * auditctl -a task,always -F uid= */ /* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */ /* XXX it should be possible to do logging via the log socket safely */ #ifdef SANDBOX_SECCOMP_FILTER_DEBUG /* Use the kernel headers in case of an older toolchain. */ # include # define __have_siginfo_t 1 # define __have_sigval_t 1 # define __have_sigevent_t 1 #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ #include "includes.h" #ifdef SANDBOX_SECCOMP_FILTER #include #include #include #include #include #include #include #include #include #include #include #include #include /* for offsetof */ #include #include #include #include #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" /* Linux seccomp_filter sandbox */ #define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL /* Use a signal handler to emit violations when debugging */ #ifdef SANDBOX_SECCOMP_FILTER_DEBUG # undef SECCOMP_FILTER_FAIL # define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ /* Simple helpers to avoid manual errors (but larger BPF programs). */ #define SC_DENY(_nr, _errno) \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) #define SC_ALLOW(_nr) \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \ /* load first syscall argument */ \ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ offsetof(struct seccomp_data, args[(_arg_nr)])), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ /* reload syscall number; all rules expect it in accumulator */ \ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ offsetof(struct seccomp_data, nr)) /* Syscall filtering set for preauth. */ static const struct sock_filter preauth_insns[] = { /* Ensure the syscall arch convention is as expected. */ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, arch)), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), /* Load the syscall number for checking. */ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)), /* Syscalls to non-fatally deny */ #ifdef __NR_fstat SC_DENY(fstat, EACCES), #endif #ifdef __NR_fstat64 SC_DENY(fstat64, EACCES), #endif #ifdef __NR_open SC_DENY(open, EACCES), #endif #ifdef __NR_openat SC_DENY(openat, EACCES), #endif #ifdef __NR_newfstatat SC_DENY(newfstatat, EACCES), #endif #ifdef __NR_stat SC_DENY(stat, EACCES), #endif #ifdef __NR_stat64 SC_DENY(stat64, EACCES), #endif /* Syscalls to permit */ #ifdef __NR_brk SC_ALLOW(brk), #endif #ifdef __NR_clock_gettime SC_ALLOW(clock_gettime), #endif #ifdef __NR_close SC_ALLOW(close), #endif #ifdef __NR_exit SC_ALLOW(exit), #endif #ifdef __NR_exit_group SC_ALLOW(exit_group), #endif #ifdef __NR_getpgid SC_ALLOW(getpgid), #endif #ifdef __NR_getpid SC_ALLOW(getpid), #endif #ifdef __NR_getrandom SC_ALLOW(getrandom), #endif #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), #endif #ifdef __NR_madvise SC_ALLOW(madvise), #endif #ifdef __NR_mmap SC_ALLOW(mmap), #endif #ifdef __NR_mmap2 SC_ALLOW(mmap2), #endif #ifdef __NR_mremap SC_ALLOW(mremap), #endif #ifdef __NR_munmap SC_ALLOW(munmap), #endif #ifdef __NR__newselect SC_ALLOW(_newselect), #endif #ifdef __NR_poll SC_ALLOW(poll), #endif #ifdef __NR_pselect6 SC_ALLOW(pselect6), #endif #ifdef __NR_read SC_ALLOW(read), #endif #ifdef __NR_rt_sigprocmask SC_ALLOW(rt_sigprocmask), #endif #ifdef __NR_select SC_ALLOW(select), #endif #ifdef __NR_shutdown SC_ALLOW(shutdown), #endif #ifdef __NR_sigprocmask SC_ALLOW(sigprocmask), #endif #ifdef __NR_time SC_ALLOW(time), #endif #ifdef __NR_write SC_ALLOW(write), #endif #ifdef __NR_socketcall SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), #endif /* Default deny */ BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), }; static const struct sock_fprog preauth_program = { .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])), .filter = (struct sock_filter *)preauth_insns, }; struct ssh_sandbox { pid_t child_pid; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; /* * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ debug3("%s: preparing seccomp filter sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->child_pid = 0; return box; } #ifdef SANDBOX_SECCOMP_FILTER_DEBUG extern struct monitor *pmonitor; void mm_log_handler(LogLevel level, const char *msg, void *ctx); static void ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) { char msg[256]; snprintf(msg, sizeof(msg), "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)", __func__, info->si_arch, info->si_syscall, info->si_call_addr); mm_log_handler(SYSLOG_LEVEL_FATAL, msg, pmonitor); _exit(1); } static void ssh_sandbox_child_debugging(void) { struct sigaction act; sigset_t mask; debug3("%s: installing SIGSYS handler", __func__); memset(&act, 0, sizeof(act)); sigemptyset(&mask); sigaddset(&mask, SIGSYS); act.sa_sigaction = &ssh_sandbox_violation; act.sa_flags = SA_SIGINFO; if (sigaction(SIGSYS, &act, NULL) == -1) fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) fatal("%s: sigprocmask(SIGSYS): %s", __func__, strerror(errno)); } #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ void ssh_sandbox_child(struct ssh_sandbox *box) { struct rlimit rl_zero; int nnp_failed = 0; /* Set rlimits for completeness if possible. */ rl_zero.rlim_cur = rl_zero.rlim_max = 0; if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", __func__, strerror(errno)); if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", __func__, strerror(errno)); if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", __func__, strerror(errno)); #ifdef SANDBOX_SECCOMP_FILTER_DEBUG ssh_sandbox_child_debugging(); #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", __func__, strerror(errno)); nnp_failed = 1; } debug3("%s: attaching seccomp filter program", __func__); if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) debug("%s: prctl(PR_SET_SECCOMP): %s", __func__, strerror(errno)); else if (nnp_failed) fatal("%s: SECCOMP_MODE_FILTER activated but " "PR_SET_NO_NEW_PRIVS failed", __func__); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { box->child_pid = child_pid; } #endif /* SANDBOX_SECCOMP_FILTER */ openssh-7.2p2/sandbox-solaris.c010064400017500001750000000053571267006270000147400ustar00djmdjm/* * Copyright (c) 2015 Joyent, Inc * Author: Alex Wilson * * 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" #ifdef SANDBOX_SOLARIS #ifndef USE_SOLARIS_PRIVS # error "--with-solaris-privs must be used with the Solaris sandbox" #endif #include #include #include #include #include #include #include #ifdef HAVE_PRIV_H # include #endif #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" struct ssh_sandbox { priv_set_t *pset; }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box = NULL; box = xcalloc(1, sizeof(*box)); /* Start with "basic" and drop everything we don't need. */ box->pset = solaris_basic_privset(); if (box->pset == NULL) { free(box); return NULL; } /* Drop everything except the ability to use already-opened files */ if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 || #ifdef PRIV_NET_ACCESS priv_delset(box->pset, PRIV_NET_ACCESS) != 0 || #endif priv_delset(box->pset, PRIV_PROC_EXEC) != 0 || priv_delset(box->pset, PRIV_PROC_FORK) != 0 || priv_delset(box->pset, PRIV_PROC_INFO) != 0 || priv_delset(box->pset, PRIV_PROC_SESSION) != 0) { free(box); return NULL; } /* These may not be available on older Solaris-es */ # if defined(PRIV_FILE_READ) && defined(PRIV_FILE_WRITE) if (priv_delset(box->pset, PRIV_FILE_READ) != 0 || priv_delset(box->pset, PRIV_FILE_WRITE) != 0) { free(box); return NULL; } # endif return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { if (setppriv(PRIV_SET, PRIV_PERMITTED, box->pset) != 0 || setppriv(PRIV_SET, PRIV_LIMIT, box->pset) != 0 || setppriv(PRIV_SET, PRIV_INHERITABLE, box->pset) != 0) fatal("setppriv: %s", strerror(errno)); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { priv_freeset(box->pset); box->pset = NULL; free(box); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { /* Nothing to do here */ } #endif /* SANDBOX_SOLARIS */ openssh-7.2p2/sandbox-systrace.c010064400017500001750000000143501267006270000151120ustar00djmdjm/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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" #ifdef SANDBOX_SYSTRACE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "atomicio.h" #include "log.h" #include "ssh-sandbox.h" #include "xmalloc.h" struct sandbox_policy { int syscall; int action; }; /* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ static const struct sandbox_policy preauth_policy[] = { { SYS_exit, SYSTR_POLICY_PERMIT }, #ifdef SYS_kbind { SYS_kbind, SYSTR_POLICY_PERMIT }, #endif { SYS_getpid, SYSTR_POLICY_PERMIT }, { SYS_getpgid, SYSTR_POLICY_PERMIT }, { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, #ifdef SYS_getentropy /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ { SYS_getentropy, SYSTR_POLICY_PERMIT }, #else /* Previous releases used sysctl(3)'s kern.arnd variable. */ { SYS___sysctl, SYSTR_POLICY_PERMIT }, #endif #ifdef SYS_sendsyslog { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, #endif { SYS_madvise, SYSTR_POLICY_PERMIT }, { SYS_mmap, SYSTR_POLICY_PERMIT }, { SYS_mprotect, SYSTR_POLICY_PERMIT }, { SYS_mquery, SYSTR_POLICY_PERMIT }, { SYS_munmap, SYSTR_POLICY_PERMIT }, { SYS_poll, SYSTR_POLICY_PERMIT }, { SYS_select, SYSTR_POLICY_PERMIT }, { SYS_read, SYSTR_POLICY_PERMIT }, { SYS_write, SYSTR_POLICY_PERMIT }, { SYS_shutdown, SYSTR_POLICY_PERMIT }, { SYS_close, SYSTR_POLICY_PERMIT }, { SYS_open, SYSTR_POLICY_NEVER }, { -1, -1 } }; struct ssh_sandbox { int systrace_fd; pid_t child_pid; void (*osigchld)(int); }; struct ssh_sandbox * ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; debug3("%s: preparing systrace sandbox", __func__); box = xcalloc(1, sizeof(*box)); box->systrace_fd = -1; box->child_pid = 0; box->osigchld = signal(SIGCHLD, SIG_IGN); return box; } void ssh_sandbox_child(struct ssh_sandbox *box) { debug3("%s: ready", __func__); signal(SIGCHLD, box->osigchld); if (kill(getpid(), SIGSTOP) != 0) fatal("%s: kill(%d, SIGSTOP)", __func__, getpid()); debug3("%s: started", __func__); } static void ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, const struct sandbox_policy *allowed_syscalls) { int dev_systrace, i, j, found, status; pid_t pid; struct systrace_policy policy; /* Wait for the child to send itself a SIGSTOP */ debug3("%s: wait for child %ld", __func__, (long)child_pid); do { pid = waitpid(child_pid, &status, WUNTRACED); } while (pid == -1 && errno == EINTR); signal(SIGCHLD, box->osigchld); if (!WIFSTOPPED(status)) { if (WIFSIGNALED(status)) fatal("%s: child terminated with signal %d", __func__, WTERMSIG(status)); if (WIFEXITED(status)) fatal("%s: child exited with status %d", __func__, WEXITSTATUS(status)); fatal("%s: child not stopped", __func__); } debug3("%s: child %ld stopped", __func__, (long)child_pid); box->child_pid = child_pid; /* Set up systracing of child */ if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1) fatal("%s: open(\"/dev/systrace\"): %s", __func__, strerror(errno)); if (ioctl(dev_systrace, STRIOCCLONE, &box->systrace_fd) == -1) fatal("%s: ioctl(STRIOCCLONE, %d): %s", __func__, dev_systrace, strerror(errno)); close(dev_systrace); debug3("%s: systrace attach, fd=%d", __func__, box->systrace_fd); if (ioctl(box->systrace_fd, STRIOCATTACH, &child_pid) == -1) fatal("%s: ioctl(%d, STRIOCATTACH, %d): %s", __func__, box->systrace_fd, child_pid, strerror(errno)); /* Allocate and assign policy */ memset(&policy, 0, sizeof(policy)); policy.strp_op = SYSTR_POLICY_NEW; policy.strp_maxents = SYS_MAXSYSCALL; if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, box->systrace_fd, strerror(errno)); policy.strp_op = SYSTR_POLICY_ASSIGN; policy.strp_pid = box->child_pid; if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", __func__, box->systrace_fd, strerror(errno)); /* Set per-syscall policy */ for (i = 0; i < SYS_MAXSYSCALL; i++) { found = 0; for (j = 0; allowed_syscalls[j].syscall != -1; j++) { if (allowed_syscalls[j].syscall == i) { found = 1; break; } } policy.strp_op = SYSTR_POLICY_MODIFY; policy.strp_code = i; policy.strp_policy = found ? allowed_syscalls[j].action : SYSTR_POLICY_KILL; if (found) debug3("%s: policy: enable syscall %d", __func__, i); if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", __func__, box->systrace_fd, strerror(errno)); } /* Signal the child to start running */ debug3("%s: start child %ld", __func__, (long)child_pid); if (kill(box->child_pid, SIGCONT) != 0) fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid); } void ssh_sandbox_parent_finish(struct ssh_sandbox *box) { /* Closing this before the child exits will terminate it */ close(box->systrace_fd); free(box); debug3("%s: finished", __func__); } void ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) { ssh_sandbox_parent(box, child_pid, preauth_policy); } #endif /* SANDBOX_SYSTRACE */ openssh-7.2p2/sc25519.c010064400017500001750000000162441267006270000126400ustar00djmdjm/* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c */ #include "includes.h" #include "sc25519.h" /*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; static crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ { unsigned int x = a; x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ x >>= 31; /* 0: no; 1: yes */ return x; } /* Reduce coefficients of r before calling reduce_add_sub */ static void reduce_add_sub(sc25519 *r) { crypto_uint32 pb = 0; crypto_uint32 b; crypto_uint32 mask; int i; unsigned char t[32]; for(i=0;i<32;i++) { pb += m[i]; b = lt(r->v[i],pb); t[i] = r->v[i]-pb+(b<<8); pb = b; } mask = b - 1; for(i=0;i<32;i++) r->v[i] ^= mask & (r->v[i] ^ t[i]); } /* Reduce coefficients of x before calling barrett_reduce */ static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) { /* See HAC, Alg. 14.42 */ int i,j; crypto_uint32 q2[66]; crypto_uint32 *q3 = q2 + 33; crypto_uint32 r1[33]; crypto_uint32 r2[33]; crypto_uint32 carry; crypto_uint32 pb = 0; crypto_uint32 b; for (i = 0;i < 66;++i) q2[i] = 0; for (i = 0;i < 33;++i) r2[i] = 0; for(i=0;i<33;i++) for(j=0;j<33;j++) if(i+j >= 31) q2[i+j] += mu[i]*x[j+31]; carry = q2[31] >> 8; q2[32] += carry; carry = q2[32] >> 8; q2[33] += carry; for(i=0;i<33;i++)r1[i] = x[i]; for(i=0;i<32;i++) for(j=0;j<33;j++) if(i+j < 33) r2[i+j] += m[i]*q3[j]; for(i=0;i<32;i++) { carry = r2[i] >> 8; r2[i+1] += carry; r2[i] &= 0xff; } for(i=0;i<32;i++) { pb += r2[i]; b = lt(r1[i],pb); r->v[i] = r1[i]-pb+(b<<8); pb = b; } /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 * If so: Handle it here! */ reduce_add_sub(r); reduce_add_sub(r); } void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) { int i; crypto_uint32 t[64]; for(i=0;i<32;i++) t[i] = x[i]; for(i=32;i<64;++i) t[i] = 0; barrett_reduce(r, t); } void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]) { int i; for(i=0;i<16;i++) r->v[i] = x[i]; } void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) { int i; crypto_uint32 t[64]; for(i=0;i<64;i++) t[i] = x[i]; barrett_reduce(r, t); } void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x) { int i; for(i=0;i<16;i++) r->v[i] = x->v[i]; for(i=0;i<16;i++) r->v[16+i] = 0; } void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) { int i; for(i=0;i<32;i++) r[i] = x->v[i]; } int sc25519_iszero_vartime(const sc25519 *x) { int i; for(i=0;i<32;i++) if(x->v[i] != 0) return 0; return 1; } int sc25519_isshort_vartime(const sc25519 *x) { int i; for(i=31;i>15;i--) if(x->v[i] != 0) return 0; return 1; } int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y) { int i; for(i=31;i>=0;i--) { if(x->v[i] < y->v[i]) return 1; if(x->v[i] > y->v[i]) return 0; } return 0; } void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y) { int i, carry; for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; for(i=0;i<31;i++) { carry = r->v[i] >> 8; r->v[i+1] += carry; r->v[i] &= 0xff; } reduce_add_sub(r); } void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y) { crypto_uint32 b = 0; crypto_uint32 t; int i; for(i=0;i<32;i++) { t = x->v[i] - y->v[i] - b; r->v[i] = t & 255; b = (t >> 8) & 1; } } void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y) { int i,j,carry; crypto_uint32 t[64]; for(i=0;i<64;i++)t[i] = 0; for(i=0;i<32;i++) for(j=0;j<32;j++) t[i+j] += x->v[i] * y->v[j]; /* Reduce coefficients */ for(i=0;i<63;i++) { carry = t[i] >> 8; t[i+1] += carry; t[i] &= 0xff; } barrett_reduce(r, t); } void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y) { sc25519 t; sc25519_from_shortsc(&t, y); sc25519_mul(r, x, &t); } void sc25519_window3(signed char r[85], const sc25519 *s) { char carry; int i; for(i=0;i<10;i++) { r[8*i+0] = s->v[3*i+0] & 7; r[8*i+1] = (s->v[3*i+0] >> 3) & 7; r[8*i+2] = (s->v[3*i+0] >> 6) & 7; r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; r[8*i+3] = (s->v[3*i+1] >> 1) & 7; r[8*i+4] = (s->v[3*i+1] >> 4) & 7; r[8*i+5] = (s->v[3*i+1] >> 7) & 7; r[8*i+5] ^= (s->v[3*i+2] << 1) & 7; r[8*i+6] = (s->v[3*i+2] >> 2) & 7; r[8*i+7] = (s->v[3*i+2] >> 5) & 7; } r[8*i+0] = s->v[3*i+0] & 7; r[8*i+1] = (s->v[3*i+0] >> 3) & 7; r[8*i+2] = (s->v[3*i+0] >> 6) & 7; r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; r[8*i+3] = (s->v[3*i+1] >> 1) & 7; r[8*i+4] = (s->v[3*i+1] >> 4) & 7; /* Making it signed */ carry = 0; for(i=0;i<84;i++) { r[i] += carry; r[i+1] += r[i] >> 3; r[i] &= 7; carry = r[i] >> 2; r[i] -= carry<<3; } r[84] += carry; } void sc25519_window5(signed char r[51], const sc25519 *s) { char carry; int i; for(i=0;i<6;i++) { r[8*i+0] = s->v[5*i+0] & 31; r[8*i+1] = (s->v[5*i+0] >> 5) & 31; r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; r[8*i+2] = (s->v[5*i+1] >> 2) & 31; r[8*i+3] = (s->v[5*i+1] >> 7) & 31; r[8*i+3] ^= (s->v[5*i+2] << 1) & 31; r[8*i+4] = (s->v[5*i+2] >> 4) & 31; r[8*i+4] ^= (s->v[5*i+3] << 4) & 31; r[8*i+5] = (s->v[5*i+3] >> 1) & 31; r[8*i+6] = (s->v[5*i+3] >> 6) & 31; r[8*i+6] ^= (s->v[5*i+4] << 2) & 31; r[8*i+7] = (s->v[5*i+4] >> 3) & 31; } r[8*i+0] = s->v[5*i+0] & 31; r[8*i+1] = (s->v[5*i+0] >> 5) & 31; r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; r[8*i+2] = (s->v[5*i+1] >> 2) & 31; /* Making it signed */ carry = 0; for(i=0;i<50;i++) { r[i] += carry; r[i+1] += r[i] >> 5; r[i] &= 31; carry = r[i] >> 4; r[i] -= carry<<5; } r[50] += carry; } void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) { int i; for(i=0;i<31;i++) { r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2); r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); } r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2); r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2); r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2); } openssh-7.2p2/sc25519.h010064400017500001750000000055151267006270000126440ustar00djmdjm/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, * Peter Schwabe, Bo-Yin Yang. * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h */ #ifndef SC25519_H #define SC25519_H #include "crypto_api.h" #define sc25519 crypto_sign_ed25519_ref_sc25519 #define shortsc25519 crypto_sign_ed25519_ref_shortsc25519 #define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes #define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes #define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes #define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc #define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes #define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime #define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime #define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime #define sc25519_add crypto_sign_ed25519_ref_sc25519_add #define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored #define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul #define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc #define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3 #define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5 #define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2 typedef struct { crypto_uint32 v[32]; } sc25519; typedef struct { crypto_uint32 v[16]; } shortsc25519; void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]); void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x); void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); int sc25519_iszero_vartime(const sc25519 *x); int sc25519_isshort_vartime(const sc25519 *x); int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y); void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y); void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y); /* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3 * with r[i] in {-4,...,3} */ void sc25519_window3(signed char r[85], const sc25519 *s); /* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5 * with r[i] in {-16,...,15} */ void sc25519_window5(signed char r[51], const sc25519 *s); void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2); #endif openssh-7.2p2/scard004075500017500001750000000000001267006270000124725ustar00djmdjmopenssh-7.2p2/scard/.cvsignore010064400017500001750000000000211267006270000145370ustar00djmdjmMakefile Ssh.bin openssh-7.2p2/scp.1010064400017500001750000000120561267006270000123250ustar00djmdjm.\" .\" scp.1 .\" .\" Author: Tatu Ylonen .\" .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland .\" All rights reserved .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" .\" $OpenBSD: scp.1,v 1.68 2015/09/25 18:19:54 jmc Exp $ .\" .Dd $Mdocdate: September 25 2015 $ .Dt SCP 1 .Os .Sh NAME .Nm scp .Nd secure copy (remote file copy program) .Sh SYNOPSIS .Nm scp .Bk -words .Op Fl 12346BCpqrv .Op Fl c Ar cipher .Op Fl F Ar ssh_config .Op Fl i Ar identity_file .Op Fl l Ar limit .Op Fl o Ar ssh_option .Op Fl P Ar port .Op Fl S Ar program .Sm off .Oo .Op Ar user No @ .Ar host1 : .Oc Ar file1 .Sm on .Ar ... .Sm off .Oo .Op Ar user No @ .Ar host2 : .Oc Ar file2 .Sm on .Ek .Sh DESCRIPTION .Nm copies files between hosts on a network. It uses .Xr ssh 1 for data transfer, and uses the same authentication and provides the same security as .Xr ssh 1 . .Nm will ask for passwords or passphrases if they are needed for authentication. .Pp File names may contain a user and host specification to indicate that the file is to be copied to/from that host. Local file names can be made explicit using absolute or relative pathnames to avoid .Nm treating file names containing .Sq :\& as host specifiers. Copies between two remote hosts are also permitted. .Pp The options are as follows: .Bl -tag -width Ds .It Fl 1 Forces .Nm to use protocol 1. .It Fl 2 Forces .Nm to use protocol 2. .It Fl 3 Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts. Note that this option disables the progress meter. .It Fl 4 Forces .Nm to use IPv4 addresses only. .It Fl 6 Forces .Nm to use IPv6 addresses only. .It Fl B Selects batch mode (prevents asking for passwords or passphrases). .It Fl C Compression enable. Passes the .Fl C flag to .Xr ssh 1 to enable compression. .It Fl c Ar cipher Selects the cipher to use for encrypting the data transfer. This option is directly passed to .Xr ssh 1 . .It Fl F Ar ssh_config Specifies an alternative per-user configuration file for .Nm ssh . This option is directly passed to .Xr ssh 1 . .It Fl i Ar identity_file Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to .Xr ssh 1 . .It Fl l Ar limit Limits the used bandwidth, specified in Kbit/s. .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh in the format used in .Xr ssh_config 5 . This is useful for specifying options for which there is no separate .Nm scp command-line flag. For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact .It AddressFamily .It BatchMode .It BindAddress .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs .It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher .It Ciphers .It Compression .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout .It ControlMaster .It ControlPath .It ControlPersist .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials .It HashKnownHosts .It Host .It HostbasedAuthentication .It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName .It IdentityFile .It IdentitiesOnly .It IPQoS .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication .It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol .It ProxyCommand .It PubkeyAcceptedKeyTypes .It PubkeyAuthentication .It RekeyLimit .It RhostsRSAAuthentication .It RSAAuthentication .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It StrictHostKeyChecking .It TCPKeepAlive .It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile .It VerifyHostKeyDNS .El .It Fl P Ar port Specifies the port to connect to on the remote host. Note that this option is written with a capital .Sq P , because .Fl p is already reserved for preserving the times and modes of the file. .It Fl p Preserves modification times, access times, and modes from the original file. .It Fl q Quiet mode: disables the progress meter as well as warning and diagnostic messages from .Xr ssh 1 . .It Fl r Recursively copy entire directories. Note that .Nm follows symbolic links encountered in the tree traversal. .It Fl S Ar program Name of .Ar program to use for the encrypted connection. The program must understand .Xr ssh 1 options. .It Fl v Verbose mode. Causes .Nm and .Xr ssh 1 to print debugging messages about their progress. This is helpful in debugging connection, authentication, and configuration problems. .El .Sh EXIT STATUS .Ex -std scp .Sh SEE ALSO .Xr sftp 1 , .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , .Xr ssh_config 5 , .Xr sshd 8 .Sh HISTORY .Nm is based on the rcp program in .Bx source code from the Regents of the University of California. .Sh AUTHORS .An Timo Rinne Aq Mt tri@iki.fi .An Tatu Ylonen Aq Mt ylo@cs.hut.fi openssh-7.2p2/scp.c010064400017500001750000000770431267006270000124160ustar00djmdjm/* $OpenBSD: scp.c,v 1.184 2015/11/27 00:49:31 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). * * NOTE: This version should NOT be suid root. (This uses ssh to * do the transfer and ssh has the necessary privileges.) * * 1995 Timo Rinne , Tatu Ylonen * * 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 Theo de Raadt. All rights reserved. * Copyright (c) 1999 Aaron Campbell. 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. */ /* * Parts from: * * Copyright (c) 1983, 1990, 1992, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "includes.h" #include #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_POLL_H #include #else # ifdef HAVE_SYS_POLL_H # include # endif #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) #include #endif #include "xmalloc.h" #include "atomicio.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "progressmeter.h" extern char *__progname; #define COPY_BUFLEN 16384 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); int do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout); /* Struct for addargs */ arglist args; arglist remote_remote_args; /* Bandwidth limit */ long long limit_kbps = 0; struct bwlimit bwlimit; /* Name of current file being transferred. */ char *curfile; /* This is set to non-zero to enable verbose mode. */ int verbose_mode = 0; /* This is set to zero if the progressmeter is not desired. */ int showprogress = 1; /* * This is set to non-zero if remote-remote copy should be piped * through this process. */ int throughlocal = 0; /* This is the program to execute for the secured connection. ("ssh" or -S) */ char *ssh_program = _PATH_SSH_PROGRAM; /* This is used to store the pid of ssh_program */ pid_t do_cmd_pid = -1; static void killchild(int signo) { if (do_cmd_pid > 1) { kill(do_cmd_pid, signo ? signo : SIGTERM); waitpid(do_cmd_pid, NULL, 0); } if (signo) _exit(1); exit(1); } static void suspchild(int signo) { int status; if (do_cmd_pid > 1) { kill(do_cmd_pid, signo); while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 && errno == EINTR) ; kill(getpid(), SIGSTOP); } } static int do_local_cmd(arglist *a) { u_int i; int status; pid_t pid; if (a->num == 0) fatal("do_local_cmd: no arguments"); if (verbose_mode) { fprintf(stderr, "Executing:"); for (i = 0; i < a->num; i++) fprintf(stderr, " %s", a->list[i]); fprintf(stderr, "\n"); } if ((pid = fork()) == -1) fatal("do_local_cmd: fork: %s", strerror(errno)); if (pid == 0) { execvp(a->list[0], a->list); perror(a->list[0]); exit(1); } do_cmd_pid = pid; signal(SIGTERM, killchild); signal(SIGINT, killchild); signal(SIGHUP, killchild); while (waitpid(pid, &status, 0) == -1) if (errno != EINTR) fatal("do_local_cmd: waitpid: %s", strerror(errno)); do_cmd_pid = -1; if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) return (-1); return (0); } /* * This function executes the given command as the specified user on the * given host. This returns < 0 if execution fails, and >= 0 otherwise. This * assigns the input and output file descriptors on success. */ int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) { int pin[2], pout[2], reserved[2]; if (verbose_mode) fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n", ssh_program, host, remuser ? remuser : "(unspecified)", cmd); /* * Reserve two descriptors so that the real pipes won't get * descriptors 0 and 1 because that will screw up dup2 below. */ if (pipe(reserved) < 0) fatal("pipe: %s", strerror(errno)); /* Create a socket pair for communicating with ssh. */ if (pipe(pin) < 0) fatal("pipe: %s", strerror(errno)); if (pipe(pout) < 0) fatal("pipe: %s", strerror(errno)); /* Free the reserved descriptors. */ close(reserved[0]); close(reserved[1]); signal(SIGTSTP, suspchild); signal(SIGTTIN, suspchild); signal(SIGTTOU, suspchild); /* Fork a child to execute the command on the remote host using ssh. */ do_cmd_pid = fork(); if (do_cmd_pid == 0) { /* Child. */ close(pin[1]); close(pout[0]); dup2(pin[0], 0); dup2(pout[1], 1); close(pin[0]); close(pout[1]); replacearg(&args, 0, "%s", ssh_program); if (remuser != NULL) { addargs(&args, "-l"); addargs(&args, "%s", remuser); } addargs(&args, "--"); addargs(&args, "%s", host); addargs(&args, "%s", cmd); execvp(ssh_program, args.list); perror(ssh_program); exit(1); } else if (do_cmd_pid == -1) { fatal("fork: %s", strerror(errno)); } /* Parent. Close the other side, and return the local side. */ close(pin[0]); *fdout = pin[1]; close(pout[1]); *fdin = pout[0]; signal(SIGTERM, killchild); signal(SIGINT, killchild); signal(SIGHUP, killchild); return 0; } /* * This functions executes a command simlar to do_cmd(), but expects the * input and output descriptors to be setup by a previous call to do_cmd(). * This way the input and output of two commands can be connected. */ int do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout) { pid_t pid; int status; if (verbose_mode) fprintf(stderr, "Executing: 2nd program %s host %s, user %s, command %s\n", ssh_program, host, remuser ? remuser : "(unspecified)", cmd); /* Fork a child to execute the command on the remote host using ssh. */ pid = fork(); if (pid == 0) { dup2(fdin, 0); dup2(fdout, 1); replacearg(&args, 0, "%s", ssh_program); if (remuser != NULL) { addargs(&args, "-l"); addargs(&args, "%s", remuser); } addargs(&args, "--"); addargs(&args, "%s", host); addargs(&args, "%s", cmd); execvp(ssh_program, args.list); perror(ssh_program); exit(1); } else if (pid == -1) { fatal("fork: %s", strerror(errno)); } while (waitpid(pid, &status, 0) == -1) if (errno != EINTR) fatal("do_cmd2: waitpid: %s", strerror(errno)); return 0; } typedef struct { size_t cnt; char *buf; } BUF; BUF *allocbuf(BUF *, int, int); void lostconn(int); int okname(char *); void run_err(const char *,...); void verifydir(char *); struct passwd *pwd; uid_t userid; int errs, remin, remout; int pflag, iamremote, iamrecursive, targetshouldbedirectory; #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ int response(void); void rsource(char *, struct stat *); void sink(int, char *[]); void source(int, char *[]); void tolocal(int, char *[]); void toremote(char *, int, char *[]); void usage(void); int main(int argc, char **argv) { int ch, fflag, tflag, status, n; char *targ, **newargv; const char *errstr; extern char *optarg; extern int optind; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); /* Copy argv, because we modify it */ newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv)); for (n = 0; n < argc; n++) newargv[n] = xstrdup(argv[n]); argv = newargv; __progname = ssh_get_progname(argv[0]); memset(&args, '\0', sizeof(args)); memset(&remote_remote_args, '\0', sizeof(remote_remote_args)); args.list = remote_remote_args.list = NULL; addargs(&args, "%s", ssh_program); addargs(&args, "-x"); addargs(&args, "-oForwardAgent=no"); addargs(&args, "-oPermitLocalCommand=no"); addargs(&args, "-oClearAllForwardings=yes"); fflag = tflag = 0; while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1) switch (ch) { /* User-visible flags. */ case '1': case '2': case '4': case '6': case 'C': addargs(&args, "-%c", ch); addargs(&remote_remote_args, "-%c", ch); break; case '3': throughlocal = 1; break; case 'o': case 'c': case 'i': case 'F': addargs(&remote_remote_args, "-%c", ch); addargs(&remote_remote_args, "%s", optarg); addargs(&args, "-%c", ch); addargs(&args, "%s", optarg); break; case 'P': addargs(&remote_remote_args, "-p"); addargs(&remote_remote_args, "%s", optarg); addargs(&args, "-p"); addargs(&args, "%s", optarg); break; case 'B': addargs(&remote_remote_args, "-oBatchmode=yes"); addargs(&args, "-oBatchmode=yes"); break; case 'l': limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, &errstr); if (errstr != NULL) usage(); limit_kbps *= 1024; /* kbps */ bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN); break; case 'p': pflag = 1; break; case 'r': iamrecursive = 1; break; case 'S': ssh_program = xstrdup(optarg); break; case 'v': addargs(&args, "-v"); addargs(&remote_remote_args, "-v"); verbose_mode = 1; break; case 'q': addargs(&args, "-q"); addargs(&remote_remote_args, "-q"); showprogress = 0; break; /* Server options. */ case 'd': targetshouldbedirectory = 1; break; case 'f': /* "from" */ iamremote = 1; fflag = 1; break; case 't': /* "to" */ iamremote = 1; tflag = 1; #ifdef HAVE_CYGWIN setmode(0, O_BINARY); #endif break; default: usage(); } argc -= optind; argv += optind; if ((pwd = getpwuid(userid = getuid())) == NULL) fatal("unknown user %u", (u_int) userid); if (!isatty(STDOUT_FILENO)) showprogress = 0; if (pflag) { /* Cannot pledge: -p allows setuid/setgid files... */ } else { if (pledge("stdio rpath wpath cpath fattr tty proc exec", NULL) == -1) { perror("pledge"); exit(1); } } remin = STDIN_FILENO; remout = STDOUT_FILENO; if (fflag) { /* Follow "protocol", send data. */ (void) response(); source(argc, argv); exit(errs != 0); } if (tflag) { /* Receive data. */ sink(argc, argv); exit(errs != 0); } if (argc < 2) usage(); if (argc > 2) targetshouldbedirectory = 1; remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", iamrecursive ? " -r" : "", pflag ? " -p" : "", targetshouldbedirectory ? " -d" : ""); (void) signal(SIGPIPE, lostconn); if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ toremote(targ, argc, argv); else { if (targetshouldbedirectory) verifydir(argv[argc - 1]); tolocal(argc, argv); /* Dest is local host. */ } /* * Finally check the exit status of the ssh process, if one was forked * and no error has occurred yet */ if (do_cmd_pid != -1 && errs == 0) { if (remin != -1) (void) close(remin); if (remout != -1) (void) close(remout); if (waitpid(do_cmd_pid, &status, 0) == -1) errs = 1; else { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) errs = 1; } } exit(errs != 0); } /* Callback from atomicio6 to update progress meter and limit bandwidth */ static int scpio(void *_cnt, size_t s) { off_t *cnt = (off_t *)_cnt; *cnt += s; if (limit_kbps > 0) bandwidth_limit(&bwlimit, s); return 0; } static int do_times(int fd, int verb, const struct stat *sb) { /* strlen(2^64) == 20; strlen(10^6) == 7 */ char buf[(20 + 7 + 2) * 2 + 2]; (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n", (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime), (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime)); if (verb) { fprintf(stderr, "File mtime %lld atime %lld\n", (long long)sb->st_mtime, (long long)sb->st_atime); fprintf(stderr, "Sending file timestamps: %s", buf); } (void) atomicio(vwrite, fd, buf, strlen(buf)); return (response()); } void toremote(char *targ, int argc, char **argv) { char *bp, *host, *src, *suser, *thost, *tuser, *arg; arglist alist; int i; u_int j; memset(&alist, '\0', sizeof(alist)); alist.list = NULL; *targ++ = 0; if (*targ == 0) targ = "."; arg = xstrdup(argv[argc - 1]); if ((thost = strrchr(arg, '@'))) { /* user@host */ *thost++ = 0; tuser = arg; if (*tuser == '\0') tuser = NULL; } else { thost = arg; tuser = NULL; } if (tuser != NULL && !okname(tuser)) { free(arg); return; } for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); if (src && throughlocal) { /* extended remote to remote */ *src++ = 0; if (*src == 0) src = "."; host = strrchr(argv[i], '@'); if (host) { *host++ = 0; host = cleanhostname(host); suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; else if (!okname(suser)) continue; } else { host = cleanhostname(argv[i]); suser = NULL; } xasprintf(&bp, "%s -f %s%s", cmd, *src == '-' ? "-- " : "", src); if (do_cmd(host, suser, bp, &remin, &remout) < 0) exit(1); free(bp); host = cleanhostname(thost); xasprintf(&bp, "%s -t %s%s", cmd, *targ == '-' ? "-- " : "", targ); if (do_cmd2(host, tuser, bp, remin, remout) < 0) exit(1); free(bp); (void) close(remin); (void) close(remout); remin = remout = -1; } else if (src) { /* standard remote to remote */ freeargs(&alist); addargs(&alist, "%s", ssh_program); addargs(&alist, "-x"); addargs(&alist, "-oClearAllForwardings=yes"); addargs(&alist, "-n"); for (j = 0; j < remote_remote_args.num; j++) { addargs(&alist, "%s", remote_remote_args.list[j]); } *src++ = 0; if (*src == 0) src = "."; host = strrchr(argv[i], '@'); if (host) { *host++ = 0; host = cleanhostname(host); suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; else if (!okname(suser)) continue; addargs(&alist, "-l"); addargs(&alist, "%s", suser); } else { host = cleanhostname(argv[i]); } addargs(&alist, "--"); addargs(&alist, "%s", host); addargs(&alist, "%s", cmd); addargs(&alist, "%s", src); addargs(&alist, "%s%s%s:%s", tuser ? tuser : "", tuser ? "@" : "", thost, targ); if (do_local_cmd(&alist) != 0) errs = 1; } else { /* local to remote */ if (remin == -1) { xasprintf(&bp, "%s -t %s%s", cmd, *targ == '-' ? "-- " : "", targ); host = cleanhostname(thost); if (do_cmd(host, tuser, bp, &remin, &remout) < 0) exit(1); if (response() < 0) exit(1); free(bp); } source(1, argv + i); } } free(arg); } void tolocal(int argc, char **argv) { char *bp, *host, *src, *suser; arglist alist; int i; memset(&alist, '\0', sizeof(alist)); alist.list = NULL; for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ freeargs(&alist); addargs(&alist, "%s", _PATH_CP); if (iamrecursive) addargs(&alist, "-r"); if (pflag) addargs(&alist, "-p"); addargs(&alist, "--"); addargs(&alist, "%s", argv[i]); addargs(&alist, "%s", argv[argc-1]); if (do_local_cmd(&alist)) ++errs; continue; } *src++ = 0; if (*src == 0) src = "."; if ((host = strrchr(argv[i], '@')) == NULL) { host = argv[i]; suser = NULL; } else { *host++ = 0; suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; } host = cleanhostname(host); xasprintf(&bp, "%s -f %s%s", cmd, *src == '-' ? "-- " : "", src); if (do_cmd(host, suser, bp, &remin, &remout) < 0) { free(bp); ++errs; continue; } free(bp); sink(1, argv + argc - 1); (void) close(remin); remin = remout = -1; } } void source(int argc, char **argv) { struct stat stb; static BUF buffer; BUF *bp; off_t i, statbytes; size_t amt, nr; int fd = -1, haderr, indx; char *last, *name, buf[2048], encname[PATH_MAX]; int len; for (indx = 0; indx < argc; ++indx) { name = argv[indx]; statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) goto syserr; if (strchr(name, '\n') != NULL) { strnvis(encname, name, sizeof(encname), VIS_NL); name = encname; } if (fstat(fd, &stb) < 0) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } if (stb.st_size < 0) { run_err("%s: %s", name, "Negative file size"); goto next; } unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: break; case S_IFDIR: if (iamrecursive) { rsource(name, &stb); goto next; } /* FALLTHROUGH */ default: run_err("%s: not a regular file", name); goto next; } if ((last = strrchr(name, '/')) == NULL) last = name; else ++last; curfile = last; if (pflag) { if (do_times(remout, verbose_mode, &stb) < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), (long long)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; } continue; } if (showprogress) start_progress_meter(curfile, stb.st_size, &statbytes); set_nonblock(remout); for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; if (i + (off_t)amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { haderr = errno; memset(bp->buf + nr, 0, amt - nr); } } /* Keep writing after error to retain sync */ if (haderr) { (void)atomicio(vwrite, remout, bp->buf, amt); memset(bp->buf, 0, amt); continue; } if (atomicio6(vwrite, remout, bp->buf, amt, scpio, &statbytes) != amt) haderr = errno; } unset_nonblock(remout); if (showprogress) stop_progress_meter(); if (fd != -1) { if (close(fd) < 0 && !haderr) haderr = errno; fd = -1; } if (!haderr) (void) atomicio(vwrite, remout, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); } } void rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; char *last, *vect[1], path[PATH_MAX]; if (!(dirp = opendir(name))) { run_err("%s: %s", name, strerror(errno)); return; } last = strrchr(name, '/'); if (last == NULL) last = name; else last++; if (pflag) { if (do_times(remout, verbose_mode, statp) < 0) { closedir(dirp); return; } } (void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", (u_int) (statp->st_mode & FILEMODEMASK), 0, last); if (verbose_mode) fprintf(stderr, "Entering directory: %s", path); (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; } while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0) continue; if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) { run_err("%s/%s: name too long", name, dp->d_name); continue; } (void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name); vect[0] = path; source(1, vect); } (void) closedir(dirp); (void) atomicio(vwrite, remout, "E\n", 2); (void) response(); } void sink(int argc, char **argv) { static BUF buffer; struct stat stb; enum { YES, NO, DISPLAYED } wrerr; BUF *bp; off_t i; size_t j, count; int amt, exists, first, ofd; mode_t mode, omode, mask; off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; struct timeval tv[2]; #define atime tv[0] #define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } setimes = targisdir = 0; mask = umask(0); if (!pflag) (void) umask(mask); if (argc != 1) { run_err("ambiguous target"); exit(1); } targ = *argv; if (targetshouldbedirectory) verifydir(targ); (void) atomicio(vwrite, remout, "", 1); if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) targisdir = 1; for (first = 1;; first = 0) { cp = buf; if (atomicio(read, remin, cp, 1) != 1) return; if (*cp++ == '\n') SCREWUP("unexpected "); do { if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) SCREWUP("lost connection"); *cp++ = ch; } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); *cp = 0; if (verbose_mode) fprintf(stderr, "Sink: %s", buf); if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) (void) atomicio(vwrite, STDERR_FILENO, buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); ++errs; continue; } if (buf[0] == 'E') { (void) atomicio(vwrite, remout, "", 1); return; } if (ch == '\n') *--cp = 0; cp = buf; if (*cp == 'T') { setimes++; cp++; if (!isdigit((unsigned char)*cp)) SCREWUP("mtime.sec not present"); ull = strtoull(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("mtime.sec not delimited"); if ((time_t)ull < 0 || (unsigned long long)(time_t)ull != ull) setimes = 0; /* out of range */ mtime.tv_sec = ull; mtime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 || mtime.tv_usec > 999999) SCREWUP("mtime.usec not delimited"); if (!isdigit((unsigned char)*cp)) SCREWUP("atime.sec not present"); ull = strtoull(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("atime.sec not delimited"); if ((time_t)ull < 0 || (unsigned long long)(time_t)ull != ull) setimes = 0; /* out of range */ atime.tv_sec = ull; atime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); (void) atomicio(vwrite, remout, "", 1); continue; } if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". * In this case, the line "No match." can be returned * by the shell before the rcp command on the remote is * executed so the ^Aerror_message convention isn't * followed. */ if (first) { run_err("%s", cp); exit(1); } SCREWUP("expected control record"); } mode = 0; for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); mode = (mode << 3) | (*cp - '0'); } if (*cp++ != ' ') SCREWUP("mode not delimited"); for (size = 0; isdigit((unsigned char)*cp);) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { run_err("error: unexpected filename: %s", cp); exit(1); } if (targisdir) { static char *namebuf; static size_t cursize; size_t need; need = strlen(targ) + strlen(cp) + 250; if (need > cursize) { free(namebuf); namebuf = xmalloc(need); cursize = need; } (void) snprintf(namebuf, need, "%s%s%s", targ, strcmp(targ, "/") ? "/" : "", cp); np = namebuf; } else np = targ; curfile = cp; exists = stat(np, &stb) == 0; if (buf[0] == 'D') { int mod_flag = pflag; if (!iamrecursive) SCREWUP("received directory without -r"); if (exists) { if (!S_ISDIR(stb.st_mode)) { errno = ENOTDIR; goto bad; } if (pflag) (void) chmod(np, mode); } else { /* Handle copying from a read-only directory */ mod_flag = 1; if (mkdir(np, mode | S_IRWXU) < 0) goto bad; } vect[0] = xstrdup(np); sink(1, vect); if (setimes) { setimes = 0; if (utimes(vect[0], tv) < 0) run_err("%s: set times: %s", vect[0], strerror(errno)); } if (mod_flag) (void) chmod(vect[0], mode); free(vect[0]); continue; } omode = mode; mode |= S_IWUSR; if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; } (void) atomicio(vwrite, remout, "", 1); if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; } cp = bp->buf; wrerr = NO; statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); set_nonblock(remin); for (count = i = 0; i < size; i += bp->cnt) { amt = bp->cnt; if (i + amt > size) amt = size - i; count += amt; do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); if (j == 0) { run_err("%s", j != EPIPE ? strerror(errno) : "dropped connection"); exit(1); } amt -= j; cp += j; } while (amt > 0); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { if (atomicio(vwrite, ofd, bp->buf, count) != count) { wrerr = YES; wrerrno = errno; } } count = 0; cp = bp->buf; } } unset_nonblock(remin); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && atomicio(vwrite, ofd, bp->buf, count) != count) { wrerr = YES; wrerrno = errno; } if (wrerr == NO && (!exists || S_ISREG(stb.st_mode)) && ftruncate(ofd, size) != 0) { run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD if (fchmod(ofd, omode)) { #else /* HAVE_FCHMOD */ if (chmod(np, omode)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); wrerr = DISPLAYED; } } else { if (!exists && omode != mode) #ifdef HAVE_FCHMOD if (fchmod(ofd, omode & ~mask)) { #else /* HAVE_FCHMOD */ if (chmod(np, omode & ~mask)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); wrerr = DISPLAYED; } } if (close(ofd) == -1) { wrerr = YES; wrerrno = errno; } (void) response(); if (setimes && wrerr == NO) { setimes = 0; if (utimes(np, tv) < 0) { run_err("%s: set times: %s", np, strerror(errno)); wrerr = DISPLAYED; } } switch (wrerr) { case YES: run_err("%s: %s", np, strerror(wrerrno)); break; case NO: (void) atomicio(vwrite, remout, "", 1); break; case DISPLAYED: break; } } screwup: run_err("protocol error: %s", why); exit(1); } int response(void) { char ch, *cp, resp, rbuf[2048]; if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) lostconn(0); cp = rbuf; switch (resp) { case 0: /* ok */ return (0); default: *cp++ = resp; /* FALLTHROUGH */ case 1: /* error, followed by error msg */ case 2: /* fatal error, "" */ do { if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) lostconn(0); *cp++ = ch; } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); if (!iamremote) (void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf); ++errs; if (resp == 1) return (-1); exit(1); } /* NOTREACHED */ } void usage(void) { (void) fprintf(stderr, "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); exit(1); } void run_err(const char *fmt,...) { static FILE *fp; va_list ap; ++errs; if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) { (void) fprintf(fp, "%c", 0x01); (void) fprintf(fp, "scp: "); va_start(ap, fmt); (void) vfprintf(fp, fmt, ap); va_end(ap); (void) fprintf(fp, "\n"); (void) fflush(fp); } if (!iamremote) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } } void verifydir(char *cp) { struct stat stb; if (!stat(cp, &stb)) { if (S_ISDIR(stb.st_mode)) return; errno = ENOTDIR; } run_err("%s: %s", cp, strerror(errno)); killchild(0); } int okname(char *cp0) { int c; char *cp; cp = cp0; do { c = (int)*cp; if (c & 0200) goto bad; if (!isalpha(c) && !isdigit((unsigned char)c)) { switch (c) { case '\'': case '"': case '`': case ' ': case '#': goto bad; default: break; } } } while (*++cp); return (1); bad: fprintf(stderr, "%s: invalid user name\n", cp0); return (0); } BUF * allocbuf(BUF *bp, int fd, int blksize) { size_t size; #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE struct stat stb; if (fstat(fd, &stb) < 0) { run_err("fstat: %s", strerror(errno)); return (0); } size = roundup(stb.st_blksize, blksize); if (size == 0) size = blksize; #else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ size = blksize; #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ if (bp->cnt >= size) return (bp); if (bp->buf == NULL) bp->buf = xmalloc(size); else bp->buf = xreallocarray(bp->buf, 1, size); memset(bp->buf, 0, size); bp->cnt = size; return (bp); } void lostconn(int signo) { if (!iamremote) (void)write(STDERR_FILENO, "lost connection\n", 16); if (signo) _exit(1); else exit(1); } openssh-7.2p2/servconf.c010064400017500001750000002146321267006270000134530ustar00djmdjm /* $OpenBSD: servconf.c,v 1.285 2016/02/17 05:29:04 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UTIL_H #include #endif #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.h" #include "compat.h" #include "pathnames.h" #include "cipher.h" #include "key.h" #include "kex.h" #include "mac.h" #include "match.h" #include "channels.h" #include "groupaccess.h" #include "canohost.h" #include "packet.h" #include "hostfile.h" #include "auth.h" #include "myproposal.h" #include "digest.h" static void add_listen_addr(ServerOptions *, char *, int); static void add_one_listen_addr(ServerOptions *, char *, int); /* Use of privilege separation or not */ extern int use_privsep; extern Buffer cfg; /* Initializes the server options to their default values. */ void initialize_server_options(ServerOptions *options) { memset(options, 0, sizeof(*options)); /* Portable-specific options */ options->use_pam = -1; /* Standard Options */ options->num_ports = 0; options->ports_from_cmdline = 0; options->queued_listen_addrs = NULL; options->num_queued_listens = 0; options->listen_addrs = NULL; options->address_family = -1; options->num_host_key_files = 0; options->num_host_cert_files = 0; options->host_key_agent = NULL; options->pid_file = NULL; options->server_key_bits = -1; options->login_grace_time = -1; options->key_regeneration_time = -1; options->permit_root_login = PERMIT_NOT_SET; options->ignore_rhosts = -1; options->ignore_user_known_hosts = -1; options->print_motd = -1; options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; options->xauth_location = NULL; options->strict_modes = -1; options->tcp_keep_alive = -1; options->log_facility = SYSLOG_FACILITY_NOT_SET; options->log_level = SYSLOG_LEVEL_NOT_SET; options->rhosts_rsa_authentication = -1; options->hostbased_authentication = -1; options->hostbased_uses_name_from_packet_only = -1; options->hostbased_key_types = NULL; options->hostkeyalgorithms = NULL; options->rsa_authentication = -1; options->pubkey_authentication = -1; options->pubkey_key_types = NULL; options->kerberos_authentication = -1; options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; options->gss_cleanup_creds = -1; options->gss_strict_acceptor = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; options->permit_empty_passwd = -1; options->permit_user_env = -1; options->use_login = -1; options->compression = -1; options->rekey_limit = -1; options->rekey_interval = -1; options->allow_tcp_forwarding = -1; options->allow_streamlocal_forwarding = -1; options->allow_agent_forwarding = -1; options->num_allow_users = 0; options->num_deny_users = 0; options->num_allow_groups = 0; options->num_deny_groups = 0; options->ciphers = NULL; options->macs = NULL; options->kex_algorithms = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->fwd_opts.gateway_ports = -1; options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; options->fwd_opts.streamlocal_bind_unlink = -1; options->num_subsystems = 0; options->max_startups_begin = -1; options->max_startups_rate = -1; options->max_startups = -1; options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; options->num_authkeys_files = 0; options->num_accept_env = 0; options->permit_tun = -1; options->num_permitted_opens = -1; options->adm_forced_command = NULL; options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; options->fingerprint_hash = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ static int option_clear_or_none(const char *o) { return o == NULL || strcasecmp(o, "none") == 0; } static void assemble_algorithms(ServerOptions *o) { if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostbased_key_types) != 0 || kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) fatal("kex_assemble_names failed"); } void fill_default_server_options(ServerOptions *options) { int i; /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_2; if (options->num_host_key_files == 0) { /* fill default hostkeys for protocols */ if (options->protocol & SSH_PROTO_1) options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE; if (options->protocol & SSH_PROTO_2) { options->host_key_files[options->num_host_key_files++] = _PATH_HOST_RSA_KEY_FILE; options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE; #ifdef OPENSSL_HAS_ECC options->host_key_files[options->num_host_key_files++] = _PATH_HOST_ECDSA_KEY_FILE; #endif options->host_key_files[options->num_host_key_files++] = _PATH_HOST_ED25519_KEY_FILE; } } /* No certificates by default */ if (options->num_ports == 0) options->ports[options->num_ports++] = SSH_DEFAULT_PORT; if (options->address_family == -1) options->address_family = AF_UNSPEC; if (options->listen_addrs == NULL) add_listen_addr(options, NULL, 0); if (options->pid_file == NULL) options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); if (options->server_key_bits == -1) options->server_key_bits = 1024; if (options->login_grace_time == -1) options->login_grace_time = 120; if (options->key_regeneration_time == -1) options->key_regeneration_time = 3600; if (options->permit_root_login == PERMIT_NOT_SET) options->permit_root_login = PERMIT_NO_PASSWD; if (options->ignore_rhosts == -1) options->ignore_rhosts = 1; if (options->ignore_user_known_hosts == -1) options->ignore_user_known_hosts = 0; if (options->print_motd == -1) options->print_motd = 1; if (options->print_lastlog == -1) options->print_lastlog = 1; if (options->x11_forwarding == -1) options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) options->xauth_location = xstrdup(_PATH_XAUTH); if (options->permit_tty == -1) options->permit_tty = 1; if (options->permit_user_rc == -1) options->permit_user_rc = 1; if (options->strict_modes == -1) options->strict_modes = 1; if (options->tcp_keep_alive == -1) options->tcp_keep_alive = 1; if (options->log_facility == SYSLOG_FACILITY_NOT_SET) options->log_facility = SYSLOG_FACILITY_AUTH; if (options->log_level == SYSLOG_LEVEL_NOT_SET) options->log_level = SYSLOG_LEVEL_INFO; if (options->rhosts_rsa_authentication == -1) options->rhosts_rsa_authentication = 0; if (options->hostbased_authentication == -1) options->hostbased_authentication = 0; if (options->hostbased_uses_name_from_packet_only == -1) options->hostbased_uses_name_from_packet_only = 0; if (options->rsa_authentication == -1) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; if (options->kerberos_authentication == -1) options->kerberos_authentication = 0; if (options->kerberos_or_local_passwd == -1) options->kerberos_or_local_passwd = 1; if (options->kerberos_ticket_cleanup == -1) options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->gss_strict_acceptor == -1) options->gss_strict_acceptor = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) options->kbd_interactive_authentication = 0; if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->permit_empty_passwd == -1) options->permit_empty_passwd = 0; if (options->permit_user_env == -1) options->permit_user_env = 0; if (options->use_login == -1) options->use_login = 0; if (options->compression == -1) options->compression = COMP_DELAYED; if (options->rekey_limit == -1) options->rekey_limit = 0; if (options->rekey_interval == -1) options->rekey_interval = 0; if (options->allow_tcp_forwarding == -1) options->allow_tcp_forwarding = FORWARD_ALLOW; if (options->allow_streamlocal_forwarding == -1) options->allow_streamlocal_forwarding = FORWARD_ALLOW; if (options->allow_agent_forwarding == -1) options->allow_agent_forwarding = 1; if (options->fwd_opts.gateway_ports == -1) options->fwd_opts.gateway_ports = 0; if (options->max_startups == -1) options->max_startups = 100; if (options->max_startups_rate == -1) options->max_startups_rate = 30; /* 30% */ if (options->max_startups_begin == -1) options->max_startups_begin = 10; if (options->max_authtries == -1) options->max_authtries = DEFAULT_AUTH_FAIL_MAX; if (options->max_sessions == -1) options->max_sessions = DEFAULT_SESSIONS_MAX; if (options->use_dns == -1) options->use_dns = 0; if (options->client_alive_interval == -1) options->client_alive_interval = 0; if (options->client_alive_count_max == -1) options->client_alive_count_max = 3; if (options->num_authkeys_files == 0) { options->authorized_keys_files[options->num_authkeys_files++] = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); options->authorized_keys_files[options->num_authkeys_files++] = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_LOWDELAY; if (options->ip_qos_bulk == -1) options->ip_qos_bulk = IPTOS_THROUGHPUT; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) options->fwd_opts.streamlocal_bind_unlink = 0; if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; assemble_algorithms(options); /* Turn privilege separation and sandboxing on by default */ if (use_privsep == -1) use_privsep = PRIVSEP_ON; #define CLEAR_ON_NONE(v) \ do { \ if (option_clear_or_none(v)) { \ free(v); \ v = NULL; \ } \ } while(0) CLEAR_ON_NONE(options->pid_file); CLEAR_ON_NONE(options->xauth_location); CLEAR_ON_NONE(options->banner); CLEAR_ON_NONE(options->trusted_user_ca_keys); CLEAR_ON_NONE(options->revoked_keys_file); CLEAR_ON_NONE(options->authorized_principals_file); CLEAR_ON_NONE(options->adm_forced_command); CLEAR_ON_NONE(options->chroot_directory); for (i = 0; i < options->num_host_key_files; i++) CLEAR_ON_NONE(options->host_key_files[i]); for (i = 0; i < options->num_host_cert_files; i++) CLEAR_ON_NONE(options->host_cert_files[i]); #undef CLEAR_ON_NONE #ifndef HAVE_MMAP if (use_privsep && options->compression == 1) { error("This platform does not support both privilege " "separation and compression"); error("Compression disabled"); options->compression = 0; } #endif } /* Keyword tokens. */ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ sUsePAM, /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, sKerberosGetAFSToken, sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, sKexAlgorithms, sIPQoS, sVersionAddendum, sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDeprecated, sUnsupported } ServerOpCodes; #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) /* Textual representation of the tokens. */ static struct { const char *name; ServerOpCodes opcode; u_int flags; } keywords[] = { /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, #else { "usepam", sUnsupported, SSHCFG_GLOBAL }, #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ { "port", sPort, SSHCFG_GLOBAL }, { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, { "pidfile", sPidFile, SSHCFG_GLOBAL }, { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, { "loglevel", sLogLevel, SSHCFG_GLOBAL }, { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL }, { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ #ifdef KRB5 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, #ifdef USE_AFS { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL }, #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif #else { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, #endif { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ { "checkmail", sDeprecated, SSHCFG_GLOBAL }, { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, #ifdef DISABLE_LASTLOG { "printlastlog", sUnsupported, SSHCFG_GLOBAL }, #else { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, #endif { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, { "uselogin", sUseLogin, SSHCFG_GLOBAL }, { "compression", sCompression, SSHCFG_GLOBAL }, { "rekeylimit", sRekeyLimit, SSHCFG_ALL }, { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, { "allowusers", sAllowUsers, SSHCFG_ALL }, { "denyusers", sDenyUsers, SSHCFG_ALL }, { "allowgroups", sAllowGroups, SSHCFG_ALL }, { "denygroups", sDenyGroups, SSHCFG_ALL }, { "ciphers", sCiphers, SSHCFG_GLOBAL }, { "macs", sMacs, SSHCFG_GLOBAL }, { "protocol", sProtocol, SSHCFG_GLOBAL }, { "gatewayports", sGatewayPorts, SSHCFG_ALL }, { "subsystem", sSubsystem, SSHCFG_GLOBAL }, { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, { "maxsessions", sMaxSessions, SSHCFG_ALL }, { "banner", sBanner, SSHCFG_ALL }, { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, { "acceptenv", sAcceptEnv, SSHCFG_ALL }, { "permittunnel", sPermitTunnel, SSHCFG_ALL }, { "permittty", sPermitTTY, SSHCFG_ALL }, { "permituserrc", sPermitUserRC, SSHCFG_ALL }, { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "ipqos", sIPQoS, SSHCFG_ALL }, { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, { "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL }, { "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL }, { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; static struct { int val; char *text; } tunmode_desc[] = { { SSH_TUNMODE_NO, "no" }, { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, { SSH_TUNMODE_ETHERNET, "ethernet" }, { SSH_TUNMODE_YES, "yes" }, { -1, NULL } }; /* * Returns the number of the token pointed to by cp or sBadOption. */ static ServerOpCodes parse_token(const char *cp, const char *filename, int linenum, u_int *flags) { u_int i; for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { *flags = keywords[i].flags; return keywords[i].opcode; } error("%s: line %d: Bad configuration option: %s", filename, linenum, cp); return sBadOption; } char * derelativise_path(const char *path) { char *expanded, *ret, cwd[PATH_MAX]; if (strcasecmp(path, "none") == 0) return xstrdup("none"); expanded = tilde_expand_filename(path, getuid()); if (*expanded == '/') return expanded; if (getcwd(cwd, sizeof(cwd)) == NULL) fatal("%s: getcwd: %s", __func__, strerror(errno)); xasprintf(&ret, "%s/%s", cwd, expanded); free(expanded); return ret; } static void add_listen_addr(ServerOptions *options, char *addr, int port) { u_int i; if (port == 0) for (i = 0; i < options->num_ports; i++) add_one_listen_addr(options, addr, options->ports[i]); else add_one_listen_addr(options, addr, port); } static void add_one_listen_addr(ServerOptions *options, char *addr, int port) { struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr; memset(&hints, 0, sizeof(hints)); hints.ai_family = options->address_family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; snprintf(strport, sizeof strport, "%d", port); if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) fatal("bad addr or host: %s (%s)", addr ? addr : "", ssh_gai_strerror(gaierr)); for (ai = aitop; ai->ai_next; ai = ai->ai_next) ; ai->ai_next = options->listen_addrs; options->listen_addrs = aitop; } /* * Queue a ListenAddress to be processed once we have all of the Ports * and AddressFamily options. */ static void queue_listen_addr(ServerOptions *options, char *addr, int port) { options->queued_listen_addrs = xreallocarray( options->queued_listen_addrs, options->num_queued_listens + 1, sizeof(addr)); options->queued_listen_ports = xreallocarray( options->queued_listen_ports, options->num_queued_listens + 1, sizeof(port)); options->queued_listen_addrs[options->num_queued_listens] = xstrdup(addr); options->queued_listen_ports[options->num_queued_listens] = port; options->num_queued_listens++; } /* * Process queued (text) ListenAddress entries. */ static void process_queued_listen_addrs(ServerOptions *options) { u_int i; if (options->num_ports == 0) options->ports[options->num_ports++] = SSH_DEFAULT_PORT; if (options->address_family == -1) options->address_family = AF_UNSPEC; for (i = 0; i < options->num_queued_listens; i++) { add_listen_addr(options, options->queued_listen_addrs[i], options->queued_listen_ports[i]); free(options->queued_listen_addrs[i]); options->queued_listen_addrs[i] = NULL; } free(options->queued_listen_addrs); options->queued_listen_addrs = NULL; free(options->queued_listen_ports); options->queued_listen_ports = NULL; options->num_queued_listens = 0; } struct connection_info * get_connection_info(int populate, int use_dns) { static struct connection_info ci; if (!populate) return &ci; ci.host = get_canonical_hostname(use_dns); ci.address = get_remote_ipaddr(); ci.laddress = get_local_ipaddr(packet_get_connection_in()); ci.lport = get_local_port(); return &ci; } /* * The strategy for the Match blocks is that the config file is parsed twice. * * The first time is at startup. activep is initialized to 1 and the * directives in the global context are processed and acted on. Hitting a * Match directive unsets activep and the directives inside the block are * checked for syntax only. * * The second time is after a connection has been established but before * authentication. activep is initialized to 2 and global config directives * are ignored since they have already been processed. If the criteria in a * Match block is met, activep is set and the subsequent directives * processed and actioned until EOF or another Match block unsets it. Any * options set are copied into the main server config. * * Potential additions/improvements: * - Add Match support for pre-kex directives, eg Protocol, Ciphers. * * - Add a Tag directive (idea from David Leonard) ala pf, eg: * Match Address 192.168.0.* * Tag trusted * Match Group wheel * Tag trusted * Match Tag trusted * AllowTcpForwarding yes * GatewayPorts clientspecified * [...] * * - Add a PermittedChannelRequests directive * Match Group shell * PermittedChannelRequests session,forwarded-tcpip */ static int match_cfg_line_group(const char *grps, int line, const char *user) { int result = 0; struct passwd *pw; if (user == NULL) goto out; if ((pw = getpwnam(user)) == NULL) { debug("Can't match group at line %d because user %.100s does " "not exist", line, user); } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { debug("Can't Match group because user %.100s not in any group " "at line %d", user, line); } else if (ga_match_pattern_list(grps) != 1) { debug("user %.100s does not match group list %.100s at line %d", user, grps, line); } else { debug("user %.100s matched group list %.100s at line %d", user, grps, line); result = 1; } out: ga_free(); return result; } /* * All of the attributes on a single Match line are ANDed together, so we need * to check every attribute and set the result to zero if any attribute does * not match. */ static int match_cfg_line(char **condition, int line, struct connection_info *ci) { int result = 1, attributes = 0, port; char *arg, *attrib, *cp = *condition; if (ci == NULL) debug3("checking syntax for 'Match %s'", cp); else debug3("checking match for '%s' user %s host %s addr %s " "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", ci->host ? ci->host : "(null)", ci->address ? ci->address : "(null)", ci->laddress ? ci->laddress : "(null)", ci->lport); while ((attrib = strdelim(&cp)) && *attrib != '\0') { attributes++; if (strcasecmp(attrib, "all") == 0) { if (attributes != 1 || ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { error("'all' cannot be combined with other " "Match attributes"); return -1; } *condition = cp; return 1; } if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { error("Missing Match criteria for %s", attrib); return -1; } if (strcasecmp(attrib, "user") == 0) { if (ci == NULL || ci->user == NULL) { result = 0; continue; } if (match_pattern_list(ci->user, arg, 0) != 1) result = 0; else debug("user %.100s matched 'User %.100s' at " "line %d", ci->user, arg, line); } else if (strcasecmp(attrib, "group") == 0) { if (ci == NULL || ci->user == NULL) { result = 0; continue; } switch (match_cfg_line_group(arg, line, ci->user)) { case -1: return -1; case 0: result = 0; } } else if (strcasecmp(attrib, "host") == 0) { if (ci == NULL || ci->host == NULL) { result = 0; continue; } if (match_hostname(ci->host, arg) != 1) result = 0; else debug("connection from %.100s matched 'Host " "%.100s' at line %d", ci->host, arg, line); } else if (strcasecmp(attrib, "address") == 0) { if (ci == NULL || ci->address == NULL) { result = 0; continue; } switch (addr_match_list(ci->address, arg)) { case 1: debug("connection from %.100s matched 'Address " "%.100s' at line %d", ci->address, arg, line); break; case 0: case -1: result = 0; break; case -2: return -1; } } else if (strcasecmp(attrib, "localaddress") == 0){ if (ci == NULL || ci->laddress == NULL) { result = 0; continue; } switch (addr_match_list(ci->laddress, arg)) { case 1: debug("connection from %.100s matched " "'LocalAddress %.100s' at line %d", ci->laddress, arg, line); break; case 0: case -1: result = 0; break; case -2: return -1; } } else if (strcasecmp(attrib, "localport") == 0) { if ((port = a2port(arg)) == -1) { error("Invalid LocalPort '%s' on Match line", arg); return -1; } if (ci == NULL || ci->lport == 0) { result = 0; continue; } /* TODO support port lists */ if (port == ci->lport) debug("connection from %.100s matched " "'LocalPort %d' at line %d", ci->laddress, port, line); else result = 0; } else { error("Unsupported Match attribute %s", attrib); return -1; } } if (attributes == 0) { error("One or more attributes required for Match"); return -1; } if (ci != NULL) debug3("match %sfound", result ? "" : "not "); *condition = cp; return result; } #define WHITESPACE " \t\r\n" /* Multistate option parsing */ struct multistate { char *key; int value; }; static const struct multistate multistate_addressfamily[] = { { "inet", AF_INET }, { "inet6", AF_INET6 }, { "any", AF_UNSPEC }, { NULL, -1 } }; static const struct multistate multistate_permitrootlogin[] = { { "without-password", PERMIT_NO_PASSWD }, { "prohibit-password", PERMIT_NO_PASSWD }, { "forced-commands-only", PERMIT_FORCED_ONLY }, { "yes", PERMIT_YES }, { "no", PERMIT_NO }, { NULL, -1 } }; static const struct multistate multistate_compression[] = { { "delayed", COMP_DELAYED }, { "yes", COMP_ZLIB }, { "no", COMP_NONE }, { NULL, -1 } }; static const struct multistate multistate_gatewayports[] = { { "clientspecified", 2 }, { "yes", 1 }, { "no", 0 }, { NULL, -1 } }; static const struct multistate multistate_privsep[] = { { "yes", PRIVSEP_NOSANDBOX }, { "sandbox", PRIVSEP_ON }, { "nosandbox", PRIVSEP_NOSANDBOX }, { "no", PRIVSEP_OFF }, { NULL, -1 } }; static const struct multistate multistate_tcpfwd[] = { { "yes", FORWARD_ALLOW }, { "all", FORWARD_ALLOW }, { "no", FORWARD_DENY }, { "remote", FORWARD_REMOTE }, { "local", FORWARD_LOCAL }, { NULL, -1 } }; int process_server_config_line(ServerOptions *options, char *line, const char *filename, int linenum, int *activep, struct connection_info *connectinfo) { char *cp, **charptr, *arg, *p; int cmdline = 0, *intptr, value, value2, n, port; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; ServerOpCodes opcode; u_int i, flags = 0; size_t len; long long val64; const struct multistate *multistate_ptr; cp = line; if ((arg = strdelim(&cp)) == NULL) return 0; /* Ignore leading whitespace */ if (*arg == '\0') arg = strdelim(&cp); if (!arg || !*arg || *arg == '#') return 0; intptr = NULL; charptr = NULL; opcode = parse_token(arg, filename, linenum, &flags); if (activep == NULL) { /* We are processing a command line directive */ cmdline = 1; activep = &cmdline; } if (*activep && opcode != sMatch) debug3("%s:%d setting %s %s", filename, linenum, arg, cp); if (*activep == 0 && !(flags & SSHCFG_MATCH)) { if (connectinfo == NULL) { fatal("%s line %d: Directive '%s' is not allowed " "within a Match block", filename, linenum, arg); } else { /* this is a directive we have already processed */ while (arg) arg = strdelim(&cp); return 0; } } switch (opcode) { /* Portable-specific options */ case sUsePAM: intptr = &options->use_pam; goto parse_flag; /* Standard Options */ case sBadOption: return -1; case sPort: /* ignore ports from configfile if cmdline specifies ports */ if (options->ports_from_cmdline) return 0; if (options->num_ports >= MAX_PORTS) fatal("%s line %d: too many ports.", filename, linenum); arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing port number.", filename, linenum); options->ports[options->num_ports++] = a2port(arg); if (options->ports[options->num_ports-1] <= 0) fatal("%s line %d: Badly formatted port number.", filename, linenum); break; case sServerKeyBits: intptr = &options->server_key_bits; parse_int: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing integer value.", filename, linenum); value = atoi(arg); if (*activep && *intptr == -1) *intptr = value; break; case sLoginGraceTime: intptr = &options->login_grace_time; parse_time: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing time value.", filename, linenum); if ((value = convtime(arg)) == -1) fatal("%s line %d: invalid time value.", filename, linenum); if (*activep && *intptr == -1) *intptr = value; break; case sKeyRegenerationTime: intptr = &options->key_regeneration_time; goto parse_time; case sListenAddress: arg = strdelim(&cp); if (arg == NULL || *arg == '\0') fatal("%s line %d: missing address", filename, linenum); /* check for bare IPv6 address: no "[]" and 2 or more ":" */ if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL && strchr(p+1, ':') != NULL) { queue_listen_addr(options, arg, 0); break; } p = hpdelim(&arg); if (p == NULL) fatal("%s line %d: bad address:port usage", filename, linenum); p = cleanhostname(p); if (arg == NULL) port = 0; else if ((port = a2port(arg)) <= 0) fatal("%s line %d: bad port number", filename, linenum); queue_listen_addr(options, p, port); break; case sAddressFamily: intptr = &options->address_family; multistate_ptr = multistate_addressfamily; parse_multistate: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing argument.", filename, linenum); value = -1; for (i = 0; multistate_ptr[i].key != NULL; i++) { if (strcasecmp(arg, multistate_ptr[i].key) == 0) { value = multistate_ptr[i].value; break; } } if (value == -1) fatal("%s line %d: unsupported option \"%s\".", filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; case sHostKeyFile: intptr = &options->num_host_key_files; if (*intptr >= MAX_HOSTKEYS) fatal("%s line %d: too many host keys specified (max %d).", filename, linenum, MAX_HOSTKEYS); charptr = &options->host_key_files[*intptr]; parse_filename: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", filename, linenum); if (*activep && *charptr == NULL) { *charptr = derelativise_path(arg); /* increase optional counter */ if (intptr != NULL) *intptr = *intptr + 1; } break; case sHostKeyAgent: charptr = &options->host_key_agent; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing socket name.", filename, linenum); if (*activep && *charptr == NULL) *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? xstrdup(arg) : derelativise_path(arg); break; case sHostCertificate: intptr = &options->num_host_cert_files; if (*intptr >= MAX_HOSTKEYS) fatal("%s line %d: too many host certificates " "specified (max %d).", filename, linenum, MAX_HOSTCERTS); charptr = &options->host_cert_files[*intptr]; goto parse_filename; break; case sPidFile: charptr = &options->pid_file; goto parse_filename; case sPermitRootLogin: intptr = &options->permit_root_login; multistate_ptr = multistate_permitrootlogin; goto parse_multistate; case sIgnoreRhosts: intptr = &options->ignore_rhosts; parse_flag: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing yes/no argument.", filename, linenum); value = 0; /* silence compiler */ if (strcmp(arg, "yes") == 0) value = 1; else if (strcmp(arg, "no") == 0) value = 0; else fatal("%s line %d: Bad yes/no argument: %s", filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; case sIgnoreUserKnownHosts: intptr = &options->ignore_user_known_hosts; goto parse_flag; case sRhostsRSAAuthentication: intptr = &options->rhosts_rsa_authentication; goto parse_flag; case sHostbasedAuthentication: intptr = &options->hostbased_authentication; goto parse_flag; case sHostbasedUsesNameFromPacketOnly: intptr = &options->hostbased_uses_name_from_packet_only; goto parse_flag; case sHostbasedAcceptedKeyTypes: charptr = &options->hostbased_key_types; parse_keytypes: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) fatal("%s line %d: Bad key types '%s'.", filename, linenum, arg ? arg : ""); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case sHostKeyAlgorithms: charptr = &options->hostkeyalgorithms; goto parse_keytypes; case sRSAAuthentication: intptr = &options->rsa_authentication; goto parse_flag; case sPubkeyAuthentication: intptr = &options->pubkey_authentication; goto parse_flag; case sPubkeyAcceptedKeyTypes: charptr = &options->pubkey_key_types; goto parse_keytypes; case sKerberosAuthentication: intptr = &options->kerberos_authentication; goto parse_flag; case sKerberosOrLocalPasswd: intptr = &options->kerberos_or_local_passwd; goto parse_flag; case sKerberosTicketCleanup: intptr = &options->kerberos_ticket_cleanup; goto parse_flag; case sKerberosGetAFSToken: intptr = &options->kerberos_get_afs_token; goto parse_flag; case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; case sKbdInteractiveAuthentication: intptr = &options->kbd_interactive_authentication; goto parse_flag; case sChallengeResponseAuthentication: intptr = &options->challenge_response_authentication; goto parse_flag; case sPrintMotd: intptr = &options->print_motd; goto parse_flag; case sPrintLastLog: intptr = &options->print_lastlog; goto parse_flag; case sX11Forwarding: intptr = &options->x11_forwarding; goto parse_flag; case sX11DisplayOffset: intptr = &options->x11_display_offset; goto parse_int; case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; case sXAuthLocation: charptr = &options->xauth_location; goto parse_filename; case sPermitTTY: intptr = &options->permit_tty; goto parse_flag; case sPermitUserRC: intptr = &options->permit_user_rc; goto parse_flag; case sStrictModes: intptr = &options->strict_modes; goto parse_flag; case sTCPKeepAlive: intptr = &options->tcp_keep_alive; goto parse_flag; case sEmptyPasswd: intptr = &options->permit_empty_passwd; goto parse_flag; case sPermitUserEnvironment: intptr = &options->permit_user_env; goto parse_flag; case sUseLogin: intptr = &options->use_login; goto parse_flag; case sCompression: intptr = &options->compression; multistate_ptr = multistate_compression; goto parse_multistate; case sRekeyLimit: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if (strcmp(arg, "default") == 0) { val64 = 0; } else { if (scan_scaled(arg, &val64) == -1) fatal("%.200s line %d: Bad number '%s': %s", filename, linenum, arg, strerror(errno)); if (val64 != 0 && val64 < 16) fatal("%.200s line %d: RekeyLimit too small", filename, linenum); } if (*activep && options->rekey_limit == -1) options->rekey_limit = val64; if (cp != NULL) { /* optional rekey interval present */ if (strcmp(cp, "none") == 0) { (void)strdelim(&cp); /* discard */ break; } intptr = &options->rekey_interval; goto parse_time; } break; case sGatewayPorts: intptr = &options->fwd_opts.gateway_ports; multistate_ptr = multistate_gatewayports; goto parse_multistate; case sUseDNS: intptr = &options->use_dns; goto parse_flag; case sLogFacility: log_facility_ptr = &options->log_facility; arg = strdelim(&cp); value = log_facility_number(arg); if (value == SYSLOG_FACILITY_NOT_SET) fatal("%.200s line %d: unsupported log facility '%s'", filename, linenum, arg ? arg : ""); if (*log_facility_ptr == -1) *log_facility_ptr = (SyslogFacility) value; break; case sLogLevel: log_level_ptr = &options->log_level; arg = strdelim(&cp); value = log_level_number(arg); if (value == SYSLOG_LEVEL_NOT_SET) fatal("%.200s line %d: unsupported log level '%s'", filename, linenum, arg ? arg : ""); if (*log_level_ptr == -1) *log_level_ptr = (LogLevel) value; break; case sAllowTcpForwarding: intptr = &options->allow_tcp_forwarding; multistate_ptr = multistate_tcpfwd; goto parse_multistate; case sAllowStreamLocalForwarding: intptr = &options->allow_streamlocal_forwarding; multistate_ptr = multistate_tcpfwd; goto parse_multistate; case sAllowAgentForwarding: intptr = &options->allow_agent_forwarding; goto parse_flag; case sUsePrivilegeSeparation: intptr = &use_privsep; multistate_ptr = multistate_privsep; goto parse_multistate; case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) fatal("%s line %d: too many allow users.", filename, linenum); if (!*activep) continue; options->allow_users[options->num_allow_users++] = xstrdup(arg); } break; case sDenyUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_deny_users >= MAX_DENY_USERS) fatal("%s line %d: too many deny users.", filename, linenum); if (!*activep) continue; options->deny_users[options->num_deny_users++] = xstrdup(arg); } break; case sAllowGroups: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_groups >= MAX_ALLOW_GROUPS) fatal("%s line %d: too many allow groups.", filename, linenum); if (!*activep) continue; options->allow_groups[options->num_allow_groups++] = xstrdup(arg); } break; case sDenyGroups: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_deny_groups >= MAX_DENY_GROUPS) fatal("%s line %d: too many deny groups.", filename, linenum); if (!*activep) continue; options->deny_groups[options->num_deny_groups++] = xstrdup(arg); } break; case sCiphers: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) fatal("%s line %d: Bad SSH2 cipher spec '%s'.", filename, linenum, arg ? arg : ""); if (options->ciphers == NULL) options->ciphers = xstrdup(arg); break; case sMacs: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); if (!mac_valid(*arg == '+' ? arg + 1 : arg)) fatal("%s line %d: Bad SSH2 mac spec '%s'.", filename, linenum, arg ? arg : ""); if (options->macs == NULL) options->macs = xstrdup(arg); break; case sKexAlgorithms: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", filename, linenum, arg ? arg : ""); if (options->kex_algorithms == NULL) options->kex_algorithms = xstrdup(arg); break; case sProtocol: intptr = &options->protocol; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); value = proto_spec(arg); if (value == SSH_PROTO_UNKNOWN) fatal("%s line %d: Bad protocol spec '%s'.", filename, linenum, arg ? arg : ""); if (*intptr == SSH_PROTO_UNKNOWN) *intptr = value; break; case sSubsystem: if (options->num_subsystems >= MAX_SUBSYSTEMS) { fatal("%s line %d: too many subsystems defined.", filename, linenum); } arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing subsystem name.", filename, linenum); if (!*activep) { arg = strdelim(&cp); break; } for (i = 0; i < options->num_subsystems; i++) if (strcmp(arg, options->subsystem_name[i]) == 0) fatal("%s line %d: Subsystem '%s' already defined.", filename, linenum, arg); options->subsystem_name[options->num_subsystems] = xstrdup(arg); arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing subsystem command.", filename, linenum); options->subsystem_command[options->num_subsystems] = xstrdup(arg); /* Collect arguments (separate to executable) */ p = xstrdup(arg); len = strlen(p) + 1; while ((arg = strdelim(&cp)) != NULL && *arg != '\0') { len += 1 + strlen(arg); p = xreallocarray(p, 1, len); strlcat(p, " ", len); strlcat(p, arg, len); } options->subsystem_args[options->num_subsystems] = p; options->num_subsystems++; break; case sMaxStartups: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing MaxStartups spec.", filename, linenum); if ((n = sscanf(arg, "%d:%d:%d", &options->max_startups_begin, &options->max_startups_rate, &options->max_startups)) == 3) { if (options->max_startups_begin > options->max_startups || options->max_startups_rate > 100 || options->max_startups_rate < 1) fatal("%s line %d: Illegal MaxStartups spec.", filename, linenum); } else if (n != 1) fatal("%s line %d: Illegal MaxStartups spec.", filename, linenum); else options->max_startups = options->max_startups_begin; break; case sMaxAuthTries: intptr = &options->max_authtries; goto parse_int; case sMaxSessions: intptr = &options->max_sessions; goto parse_int; case sBanner: charptr = &options->banner; goto parse_filename; /* * These options can contain %X options expanded at * connect time, so that you can specify paths like: * * AuthorizedKeysFile /etc/ssh_keys/%u */ case sAuthorizedKeysFile: if (*activep && options->num_authkeys_files == 0) { while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_authkeys_files >= MAX_AUTHKEYS_FILES) fatal("%s line %d: " "too many authorized keys files.", filename, linenum); options->authorized_keys_files[ options->num_authkeys_files++] = tilde_expand_filename(arg, getuid()); } } return 0; case sAuthorizedPrincipalsFile: charptr = &options->authorized_principals_file; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", filename, linenum); if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ if (intptr != NULL) *intptr = *intptr + 1; } break; case sClientAliveInterval: intptr = &options->client_alive_interval; goto parse_time; case sClientAliveCountMax: intptr = &options->client_alive_count_max; goto parse_int; case sAcceptEnv: while ((arg = strdelim(&cp)) && *arg != '\0') { if (strchr(arg, '=') != NULL) fatal("%s line %d: Invalid environment name.", filename, linenum); if (options->num_accept_env >= MAX_ACCEPT_ENV) fatal("%s line %d: too many allow env.", filename, linenum); if (!*activep) continue; options->accept_env[options->num_accept_env++] = xstrdup(arg); } break; case sPermitTunnel: intptr = &options->permit_tun; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing yes/point-to-point/" "ethernet/no argument.", filename, linenum); value = -1; for (i = 0; tunmode_desc[i].val != -1; i++) if (strcmp(tunmode_desc[i].text, arg) == 0) { value = tunmode_desc[i].val; break; } if (value == -1) fatal("%s line %d: Bad yes/point-to-point/ethernet/" "no argument: %s", filename, linenum, arg); if (*activep && *intptr == -1) *intptr = value; break; case sMatch: if (cmdline) fatal("Match directive not supported as a command-line " "option"); value = match_cfg_line(&cp, linenum, connectinfo); if (value < 0) fatal("%s line %d: Bad Match condition", filename, linenum); *activep = value; break; case sPermitOpen: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing PermitOpen specification", filename, linenum); n = options->num_permitted_opens; /* modified later */ if (strcmp(arg, "any") == 0) { if (*activep && n == -1) { channel_clear_adm_permitted_opens(); options->num_permitted_opens = 0; } break; } if (strcmp(arg, "none") == 0) { if (*activep && n == -1) { options->num_permitted_opens = 1; channel_disable_adm_local_opens(); } break; } if (*activep && n == -1) channel_clear_adm_permitted_opens(); for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { p = hpdelim(&arg); if (p == NULL) fatal("%s line %d: missing host in PermitOpen", filename, linenum); p = cleanhostname(p); if (arg == NULL || ((port = permitopen_port(arg)) < 0)) fatal("%s line %d: bad port number in " "PermitOpen", filename, linenum); if (*activep && n == -1) options->num_permitted_opens = channel_add_adm_permitted_opens(p, port); } break; case sForceCommand: if (cp == NULL || *cp == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); len = strspn(cp, WHITESPACE); if (*activep && options->adm_forced_command == NULL) options->adm_forced_command = xstrdup(cp + len); return 0; case sChrootDirectory: charptr = &options->chroot_directory; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", filename, linenum); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case sTrustedUserCAKeys: charptr = &options->trusted_user_ca_keys; goto parse_filename; case sRevokedKeys: charptr = &options->revoked_keys_file; goto parse_filename; case sIPQoS: arg = strdelim(&cp); if ((value = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad IPQoS value: %s", filename, linenum, arg); arg = strdelim(&cp); if (arg == NULL) value2 = value; else if ((value2 = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad IPQoS value: %s", filename, linenum, arg); if (*activep) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; } break; case sVersionAddendum: if (cp == NULL || *cp == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); len = strspn(cp, WHITESPACE); if (*activep && options->version_addendum == NULL) { if (strcasecmp(cp + len, "none") == 0) options->version_addendum = xstrdup(""); else if (strchr(cp + len, '\r') != NULL) fatal("%.200s line %d: Invalid argument", filename, linenum); else options->version_addendum = xstrdup(cp + len); } return 0; case sAuthorizedKeysCommand: if (cp == NULL) fatal("%.200s line %d: Missing argument.", filename, linenum); len = strspn(cp, WHITESPACE); if (*activep && options->authorized_keys_command == NULL) { if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) fatal("%.200s line %d: AuthorizedKeysCommand " "must be an absolute path", filename, linenum); options->authorized_keys_command = xstrdup(cp + len); } return 0; case sAuthorizedKeysCommandUser: charptr = &options->authorized_keys_command_user; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing AuthorizedKeysCommandUser " "argument.", filename, linenum); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case sAuthorizedPrincipalsCommand: if (cp == NULL) fatal("%.200s line %d: Missing argument.", filename, linenum); len = strspn(cp, WHITESPACE); if (*activep && options->authorized_principals_command == NULL) { if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) fatal("%.200s line %d: " "AuthorizedPrincipalsCommand must be " "an absolute path", filename, linenum); options->authorized_principals_command = xstrdup(cp + len); } return 0; case sAuthorizedPrincipalsCommandUser: charptr = &options->authorized_principals_command_user; arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing " "AuthorizedPrincipalsCommandUser argument.", filename, linenum); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; case sAuthenticationMethods: if (options->num_auth_methods == 0) { while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_auth_methods >= MAX_AUTH_METHODS) fatal("%s line %d: " "too many authentication methods.", filename, linenum); if (auth2_methods_valid(arg, 0) != 0) fatal("%s line %d: invalid " "authentication method list.", filename, linenum); if (!*activep) continue; options->auth_methods[ options->num_auth_methods++] = xstrdup(arg); } } return 0; case sStreamLocalBindMask: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing StreamLocalBindMask " "argument.", filename, linenum); /* Parse mode in octal format */ value = strtol(arg, &p, 8); if (arg == p || value < 0 || value > 0777) fatal("%s line %d: Bad mask.", filename, linenum); if (*activep) options->fwd_opts.streamlocal_bind_mask = (mode_t)value; break; case sStreamLocalBindUnlink: intptr = &options->fwd_opts.streamlocal_bind_unlink; goto parse_flag; case sFingerprintHash: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); if ((value = ssh_digest_alg_by_name(arg)) == -1) fatal("%.200s line %d: Invalid hash algorithm \"%s\".", filename, linenum, arg); if (*activep) options->fingerprint_hash = value; break; case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); while (arg) arg = strdelim(&cp); break; case sUnsupported: logit("%s line %d: Unsupported option %s", filename, linenum, arg); while (arg) arg = strdelim(&cp); break; default: fatal("%s line %d: Missing handler for opcode %s (%d)", filename, linenum, arg, opcode); } if ((arg = strdelim(&cp)) != NULL && *arg != '\0') fatal("%s line %d: garbage at end of line; \"%.200s\".", filename, linenum, arg); return 0; } /* Reads the server configuration file. */ void load_server_config(const char *filename, Buffer *conf) { char line[4096], *cp; FILE *f; int lineno = 0; debug2("%s: filename %s", __func__, filename); if ((f = fopen(filename, "r")) == NULL) { perror(filename); exit(1); } buffer_clear(conf); while (fgets(line, sizeof(line), f)) { lineno++; if (strlen(line) == sizeof(line) - 1) fatal("%s line %d too long", filename, lineno); /* * Trim out comments and strip whitespace * NB - preserve newlines, they are needed to reproduce * line numbers later for error messages */ if ((cp = strchr(line, '#')) != NULL) memcpy(cp, "\n", 2); cp = line + strspn(line, " \t\r"); buffer_append(conf, cp, strlen(cp)); } buffer_append(conf, "\0", 1); fclose(f); debug2("%s: done config len = %d", __func__, buffer_len(conf)); } void parse_server_match_config(ServerOptions *options, struct connection_info *connectinfo) { ServerOptions mo; initialize_server_options(&mo); parse_server_config(&mo, "reprocess config", &cfg, connectinfo); copy_set_server_options(options, &mo, 0); } int parse_server_match_testspec(struct connection_info *ci, char *spec) { char *p; while ((p = strsep(&spec, ",")) && *p != '\0') { if (strncmp(p, "addr=", 5) == 0) { ci->address = xstrdup(p + 5); } else if (strncmp(p, "host=", 5) == 0) { ci->host = xstrdup(p + 5); } else if (strncmp(p, "user=", 5) == 0) { ci->user = xstrdup(p + 5); } else if (strncmp(p, "laddr=", 6) == 0) { ci->laddress = xstrdup(p + 6); } else if (strncmp(p, "lport=", 6) == 0) { ci->lport = a2port(p + 6); if (ci->lport == -1) { fprintf(stderr, "Invalid port '%s' in test mode" " specification %s\n", p+6, p); return -1; } } else { fprintf(stderr, "Invalid test mode specification %s\n", p); return -1; } } return 0; } /* * returns 1 for a complete spec, 0 for partial spec and -1 for an * empty spec. */ int server_match_spec_complete(struct connection_info *ci) { if (ci->user && ci->host && ci->address) return 1; /* complete */ if (!ci->user && !ci->host && !ci->address) return -1; /* empty */ return 0; /* partial */ } /* * Copy any supported values that are set. * * If the preauth flag is set, we do not bother copying the string or * array values that are not used pre-authentication, because any that we * do use must be explictly sent in mm_getpwnamallow(). */ void copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) { #define M_CP_INTOPT(n) do {\ if (src->n != -1) \ dst->n = src->n; \ } while (0) M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); M_CP_INTOPT(rsa_authentication); M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); M_CP_INTOPT(hostbased_uses_name_from_packet_only); M_CP_INTOPT(kbd_interactive_authentication); M_CP_INTOPT(permit_root_login); M_CP_INTOPT(permit_empty_passwd); M_CP_INTOPT(allow_tcp_forwarding); M_CP_INTOPT(allow_streamlocal_forwarding); M_CP_INTOPT(allow_agent_forwarding); M_CP_INTOPT(permit_tun); M_CP_INTOPT(fwd_opts.gateway_ports); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); M_CP_INTOPT(max_sessions); M_CP_INTOPT(max_authtries); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); /* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */ #define M_CP_STROPT(n) do {\ if (src->n != NULL && dst->n != src->n) { \ free(dst->n); \ dst->n = src->n; \ } \ } while(0) #define M_CP_STRARRAYOPT(n, num_n) do {\ if (src->num_n != 0) { \ for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ } \ } while(0) /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); /* Arguments that accept '+...' need to be expanded */ assemble_algorithms(dst); /* * The only things that should be below this point are string options * which are only used after authentication. */ if (preauth) return; /* These options may be "none" to clear a global setting */ M_CP_STROPT(adm_forced_command); if (option_clear_or_none(dst->adm_forced_command)) { free(dst->adm_forced_command); dst->adm_forced_command = NULL; } M_CP_STROPT(chroot_directory); if (option_clear_or_none(dst->chroot_directory)) { free(dst->chroot_directory); dst->chroot_directory = NULL; } } #undef M_CP_INTOPT #undef M_CP_STROPT #undef M_CP_STRARRAYOPT void parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, struct connection_info *connectinfo) { int active, linenum, bad_options = 0; char *cp, *obuf, *cbuf; debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); obuf = cbuf = xstrdup(buffer_ptr(conf)); active = connectinfo ? 0 : 1; linenum = 1; while ((cp = strsep(&cbuf, "\n")) != NULL) { if (process_server_config_line(options, cp, filename, linenum++, &active, connectinfo) != 0) bad_options++; } free(obuf); if (bad_options > 0) fatal("%s: terminating, %d bad configuration options", filename, bad_options); process_queued_listen_addrs(options); } static const char * fmt_multistate_int(int val, const struct multistate *m) { u_int i; for (i = 0; m[i].key != NULL; i++) { if (m[i].value == val) return m[i].key; } return "UNKNOWN"; } static const char * fmt_intarg(ServerOpCodes code, int val) { if (val == -1) return "unset"; switch (code) { case sAddressFamily: return fmt_multistate_int(val, multistate_addressfamily); case sPermitRootLogin: return fmt_multistate_int(val, multistate_permitrootlogin); case sGatewayPorts: return fmt_multistate_int(val, multistate_gatewayports); case sCompression: return fmt_multistate_int(val, multistate_compression); case sUsePrivilegeSeparation: return fmt_multistate_int(val, multistate_privsep); case sAllowTcpForwarding: return fmt_multistate_int(val, multistate_tcpfwd); case sAllowStreamLocalForwarding: return fmt_multistate_int(val, multistate_tcpfwd); case sFingerprintHash: return ssh_digest_alg_name(val); case sProtocol: switch (val) { case SSH_PROTO_1: return "1"; case SSH_PROTO_2: return "2"; case (SSH_PROTO_1|SSH_PROTO_2): return "2,1"; default: return "UNKNOWN"; } default: switch (val) { case 0: return "no"; case 1: return "yes"; default: return "UNKNOWN"; } } } static const char * lookup_opcode_name(ServerOpCodes code) { u_int i; for (i = 0; keywords[i].name != NULL; i++) if (keywords[i].opcode == code) return(keywords[i].name); return "UNKNOWN"; } static void dump_cfg_int(ServerOpCodes code, int val) { printf("%s %d\n", lookup_opcode_name(code), val); } static void dump_cfg_oct(ServerOpCodes code, int val) { printf("%s 0%o\n", lookup_opcode_name(code), val); } static void dump_cfg_fmtint(ServerOpCodes code, int val) { printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); } static void dump_cfg_string(ServerOpCodes code, const char *val) { if (val == NULL) return; printf("%s %s\n", lookup_opcode_name(code), val == NULL ? "none" : val); } static void dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) { u_int i; for (i = 0; i < count; i++) printf("%s %s\n", lookup_opcode_name(code), vals[i]); } static void dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) { u_int i; if (count <= 0) return; printf("%s", lookup_opcode_name(code)); for (i = 0; i < count; i++) printf(" %s", vals[i]); printf("\n"); } void dump_config(ServerOptions *o) { u_int i; int ret; struct addrinfo *ai; char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; char *laddr1 = xstrdup(""), *laddr2 = NULL; /* these are usually at the top of the config */ for (i = 0; i < o->num_ports; i++) printf("port %d\n", o->ports[i]); dump_cfg_fmtint(sProtocol, o->protocol); dump_cfg_fmtint(sAddressFamily, o->address_family); /* * ListenAddress must be after Port. add_one_listen_addr pushes * addresses onto a stack, so to maintain ordering we need to * print these in reverse order. */ for (ai = o->listen_addrs; ai; ai = ai->ai_next) { if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { error("getnameinfo failed: %.100s", (ret != EAI_SYSTEM) ? gai_strerror(ret) : strerror(errno)); } else { laddr2 = laddr1; if (ai->ai_family == AF_INET6) xasprintf(&laddr1, "listenaddress [%s]:%s\n%s", addr, port, laddr2); else xasprintf(&laddr1, "listenaddress %s:%s\n%s", addr, port, laddr2); free(laddr2); } } printf("%s", laddr1); free(laddr1); /* integer arguments */ #ifdef USE_PAM dump_cfg_fmtint(sUsePAM, o->use_pam); #endif dump_cfg_int(sServerKeyBits, o->server_key_bits); dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); dump_cfg_int(sMaxAuthTries, o->max_authtries); dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); /* formatted integer arguments */ dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, o->hostbased_uses_name_from_packet_only); dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); #ifdef KRB5 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, o->kbd_interactive_authentication); dump_cfg_fmtint(sChallengeResponseAuthentication, o->challenge_response_authentication); dump_cfg_fmtint(sPrintMotd, o->print_motd); #ifndef DISABLE_LASTLOG dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); #endif dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); dump_cfg_fmtint(sPermitTTY, o->permit_tty); dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc); dump_cfg_fmtint(sStrictModes, o->strict_modes); dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); dump_cfg_string(sBanner, o->banner); dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); dump_cfg_string(sRevokedKeys, o->revoked_keys_file); dump_cfg_string(sAuthorizedPrincipalsFile, o->authorized_principals_file); dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0' ? "none" : o->version_addendum); dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? o->hostbased_key_types : KEX_DEFAULT_PK_ALG); dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? o->pubkey_key_types : KEX_DEFAULT_PK_ALG); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); /* string array arguments */ dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, o->authorized_keys_files); dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, o->host_key_files); dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, o->host_cert_files); dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); dump_cfg_strarray_oneline(sAuthenticationMethods, o->num_auth_methods, o->auth_methods); /* other arguments */ for (i = 0; i < o->num_subsystems; i++) printf("subsystem %s %s\n", o->subsystem_name[i], o->subsystem_args[i]); printf("maxstartups %d:%d:%d\n", o->max_startups_begin, o->max_startups_rate, o->max_startups); for (i = 0; tunmode_desc[i].val != -1; i++) if (tunmode_desc[i].val == o->permit_tun) { s = tunmode_desc[i].text; break; } dump_cfg_string(sPermitTunnel, s); printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); printf("%s\n", iptos2str(o->ip_qos_bulk)); printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, o->rekey_interval); channel_print_adm_permitted_opens(); } openssh-7.2p2/servconf.h010064400017500001750000000236251267006270000134600ustar00djmdjm/* $OpenBSD: servconf.h,v 1.120 2015/07/10 06:21:53 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Definitions for server configuration data and for the functions reading it. * * 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 SERVCONF_H #define SERVCONF_H #define MAX_PORTS 256 /* Max # ports. */ #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ #define MAX_DENY_USERS 256 /* Max # users on deny list. */ #define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ #define MAX_HOSTCERTS 256 /* Max # host certificates. */ #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ #define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */ #define MAX_AUTH_METHODS 256 /* Max # of AuthenticationMethods. */ /* permit_root_login */ #define PERMIT_NOT_SET -1 #define PERMIT_NO 0 #define PERMIT_FORCED_ONLY 1 #define PERMIT_NO_PASSWD 2 #define PERMIT_YES 3 /* use_privsep */ #define PRIVSEP_OFF 0 #define PRIVSEP_ON 1 #define PRIVSEP_NOSANDBOX 2 /* AllowTCPForwarding */ #define FORWARD_DENY 0 #define FORWARD_REMOTE (1) #define FORWARD_LOCAL (1<<1) #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ /* Magic name for internal sftp-server */ #define INTERNAL_SFTP_NAME "internal-sftp" typedef struct { u_int num_ports; u_int ports_from_cmdline; int ports[MAX_PORTS]; /* Port number to listen on. */ u_int num_queued_listens; char **queued_listen_addrs; int *queued_listen_ports; struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ int address_family; /* Address family used by the server. */ char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ int num_host_key_files; /* Number of files for host keys. */ char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */ int num_host_cert_files; /* Number of files for host certs. */ char *host_key_agent; /* ssh-agent socket for host keys. */ char *pid_file; /* Where to put our pid */ int server_key_bits;/* Size of the server key. */ int login_grace_time; /* Disconnect if no auth in this time * (sec). */ int key_regeneration_time; /* Server key lifetime (seconds). */ int permit_root_login; /* PERMIT_*, see above */ int ignore_rhosts; /* Ignore .rhosts and .shosts. */ int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts * for RhostsRsaAuth */ int print_motd; /* If true, print /etc/motd. */ int print_lastlog; /* If true, print lastlog */ int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ int x11_display_offset; /* What DISPLAY number to start * searching at */ int x11_use_localhost; /* If true, use localhost for fake X11 server. */ char *xauth_location; /* Location of xauth program */ int permit_tty; /* If false, deny pty allocation */ int permit_user_rc; /* If false, deny ~/.ssh/rc execution */ int strict_modes; /* If true, require string home dir modes. */ int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */ int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ char *ciphers; /* Supported SSH2 ciphers. */ char *macs; /* Supported SSH2 macs. */ char *kex_algorithms; /* SSH2 kex methods in order of preference. */ int protocol; /* Supported protocol versions. */ struct ForwardOptions fwd_opts; /* forwarding options */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for system logging. */ int rhosts_rsa_authentication; /* If true, permit rhosts RSA * authentication. */ int hostbased_authentication; /* If true, permit ssh2 hostbased auth */ int hostbased_uses_name_from_packet_only; /* experimental */ char *hostbased_key_types; /* Key types allowed for hostbased */ char *hostkeyalgorithms; /* SSH2 server key types */ int rsa_authentication; /* If true, permit RSA authentication. */ int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ char *pubkey_key_types; /* Key types allowed for public key */ int kerberos_authentication; /* If true, permit Kerberos * authentication. */ int kerberos_or_local_passwd; /* If true, permit kerberos * and any other password * authentication mechanism, * such as SecurID or * /etc/passwd */ int kerberos_ticket_cleanup; /* If true, destroy ticket * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ int challenge_response_authentication; int permit_empty_passwd; /* If false, do not permit empty * passwords. */ int permit_user_env; /* If true, read ~/.ssh/environment */ int use_login; /* If true, login(1) is used */ int compression; /* If true, compression is allowed */ int allow_tcp_forwarding; /* One of FORWARD_* */ int allow_streamlocal_forwarding; /* One of FORWARD_* */ int allow_agent_forwarding; u_int num_allow_users; char *allow_users[MAX_ALLOW_USERS]; u_int num_deny_users; char *deny_users[MAX_DENY_USERS]; u_int num_allow_groups; char *allow_groups[MAX_ALLOW_GROUPS]; u_int num_deny_groups; char *deny_groups[MAX_DENY_GROUPS]; u_int num_subsystems; char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; char *subsystem_args[MAX_SUBSYSTEMS]; u_int num_accept_env; char *accept_env[MAX_ACCEPT_ENV]; int max_startups_begin; int max_startups_rate; int max_startups; int max_authtries; int max_sessions; char *banner; /* SSH-2 banner message */ int use_dns; int client_alive_interval; /* * poke the client this often to * see if it's still there */ int client_alive_count_max; /* * If the client is unresponsive * for this many intervals above, * disconnect the session */ u_int num_authkeys_files; /* Files containing public keys */ char *authorized_keys_files[MAX_AUTHKEYS_FILES]; char *adm_forced_command; int use_pam; /* Enable auth via PAM */ int permit_tun; int num_permitted_opens; char *chroot_directory; char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_keys_command; char *authorized_keys_command_user; char *authorized_principals_file; char *authorized_principals_command; char *authorized_principals_command_user; int64_t rekey_limit; int rekey_interval; char *version_addendum; /* Appended to SSH banner */ u_int num_auth_methods; char *auth_methods[MAX_AUTH_METHODS]; int fingerprint_hash; } ServerOptions; /* Information about the incoming connection as used by Match */ struct connection_info { const char *user; const char *host; /* possibly resolved hostname */ const char *address; /* remote address */ const char *laddress; /* local address */ int lport; /* local port */ }; /* * These are string config options that must be copied between the * Match sub-config and the main config, and must be sent from the * privsep slave to the privsep master. We use a macro to ensure all * the options are copied and the copies are done in the correct order. * * NB. an option must appear in servconf.c:copy_set_server_options() or * COPY_MATCH_STRING_OPTS here but never both. */ #define COPY_MATCH_STRING_OPTS() do { \ M_CP_STROPT(banner); \ M_CP_STROPT(trusted_user_ca_keys); \ M_CP_STROPT(revoked_keys_file); \ M_CP_STROPT(authorized_keys_command); \ M_CP_STROPT(authorized_keys_command_user); \ M_CP_STROPT(authorized_principals_file); \ M_CP_STROPT(authorized_principals_command); \ M_CP_STROPT(authorized_principals_command_user); \ M_CP_STROPT(hostbased_key_types); \ M_CP_STROPT(pubkey_key_types); \ M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ M_CP_STRARRAYOPT(allow_users, num_allow_users); \ M_CP_STRARRAYOPT(deny_users, num_deny_users); \ M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \ M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ M_CP_STRARRAYOPT(accept_env, num_accept_env); \ M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \ } while (0) struct connection_info *get_connection_info(int, int); void initialize_server_options(ServerOptions *); void fill_default_server_options(ServerOptions *); int process_server_config_line(ServerOptions *, char *, const char *, int, int *, struct connection_info *); void load_server_config(const char *, Buffer *); void parse_server_config(ServerOptions *, const char *, Buffer *, struct connection_info *); void parse_server_match_config(ServerOptions *, struct connection_info *); int parse_server_match_testspec(struct connection_info *, char *); int server_match_spec_complete(struct connection_info *); void copy_set_server_options(ServerOptions *, ServerOptions *, int); void dump_config(ServerOptions *); char *derelativise_path(const char *); #endif /* SERVCONF_H */ openssh-7.2p2/serverloop.c010064400017500001750000001164551267006270000140320ustar00djmdjm/* $OpenBSD: serverloop.c,v 1.182 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Server main loop for handling the interactive session. * * 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 support by Markus Friedl. * Copyright (c) 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. */ #include "includes.h" #include /* MIN MAX */ #include #include #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "packet.h" #include "buffer.h" #include "log.h" #include "misc.h" #include "servconf.h" #include "canohost.h" #include "sshpty.h" #include "channels.h" #include "compat.h" #include "ssh1.h" #include "ssh2.h" #include "key.h" #include "cipher.h" #include "kex.h" #include "hostfile.h" #include "auth.h" #include "session.h" #include "dispatch.h" #include "auth-options.h" #include "serverloop.h" #include "ssherr.h" extern ServerOptions options; /* XXX */ extern Authctxt *the_authctxt; extern int use_privsep; static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ static Buffer stderr_buffer; /* Buffer for stderr data. */ static int fdin; /* Descriptor for stdin (for writing) */ static int fdout; /* Descriptor for stdout (for reading); May be same number as fdin. */ static int fderr; /* Descriptor for stderr. May be -1. */ static long stdin_bytes = 0; /* Number of bytes written to stdin. */ static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */ static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */ static long fdout_bytes = 0; /* Number of stdout bytes read from program. */ static int stdin_eof = 0; /* EOF message received from client. */ static int fdout_eof = 0; /* EOF encountered reading from fdout. */ static int fderr_eof = 0; /* EOF encountered readung from fderr. */ static int fdin_is_tty = 0; /* fdin points to a tty. */ static int connection_in; /* Connection to client (input). */ static int connection_out; /* Connection to client (output). */ static int connection_closed = 0; /* Connection to client closed. */ static u_int buffer_high; /* "Soft" max buffer size. */ static int no_more_sessions = 0; /* Disallow further sessions. */ /* * This SIGCHLD kludge is used to detect when the child exits. The server * will exit after that, as soon as forwarded connections have terminated. */ static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ /* Cleanup on signals (!use_privsep case only) */ static volatile sig_atomic_t received_sigterm = 0; /* prototypes */ static void server_init_dispatch(void); /* * we write to this pipe if a SIGCHLD is caught in order to avoid * the race between select() and child_terminated */ static int notify_pipe[2]; static void notify_setup(void) { if (pipe(notify_pipe) < 0) { error("pipe(notify_pipe) failed %s", strerror(errno)); } else if ((fcntl(notify_pipe[0], F_SETFD, FD_CLOEXEC) == -1) || (fcntl(notify_pipe[1], F_SETFD, FD_CLOEXEC) == -1)) { error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno)); close(notify_pipe[0]); close(notify_pipe[1]); } else { set_nonblock(notify_pipe[0]); set_nonblock(notify_pipe[1]); return; } notify_pipe[0] = -1; /* read end */ notify_pipe[1] = -1; /* write end */ } static void notify_parent(void) { if (notify_pipe[1] != -1) (void)write(notify_pipe[1], "", 1); } static void notify_prepare(fd_set *readset) { if (notify_pipe[0] != -1) FD_SET(notify_pipe[0], readset); } static void notify_done(fd_set *readset) { char c; if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) while (read(notify_pipe[0], &c, 1) != -1) debug2("notify_done: reading"); } /*ARGSUSED*/ static void sigchld_handler(int sig) { int save_errno = errno; child_terminated = 1; #ifndef _UNICOS mysignal(SIGCHLD, sigchld_handler); #endif notify_parent(); errno = save_errno; } /*ARGSUSED*/ static void sigterm_handler(int sig) { received_sigterm = sig; } /* * Make packets from buffered stderr data, and buffer it for sending * to the client. */ static void make_packets_from_stderr_data(void) { u_int len; /* Send buffered stderr data to the client. */ while (buffer_len(&stderr_buffer) > 0 && packet_not_very_much_data_to_write()) { len = buffer_len(&stderr_buffer); if (packet_is_interactive()) { if (len > 512) len = 512; } else { /* Keep the packets at reasonable size. */ if (len > packet_get_maxsize()) len = packet_get_maxsize(); } packet_start(SSH_SMSG_STDERR_DATA); packet_put_string(buffer_ptr(&stderr_buffer), len); packet_send(); buffer_consume(&stderr_buffer, len); stderr_bytes += len; } } /* * Make packets from buffered stdout data, and buffer it for sending to the * client. */ static void make_packets_from_stdout_data(void) { u_int len; /* Send buffered stdout data to the client. */ while (buffer_len(&stdout_buffer) > 0 && packet_not_very_much_data_to_write()) { len = buffer_len(&stdout_buffer); if (packet_is_interactive()) { if (len > 512) len = 512; } else { /* Keep the packets at reasonable size. */ if (len > packet_get_maxsize()) len = packet_get_maxsize(); } packet_start(SSH_SMSG_STDOUT_DATA); packet_put_string(buffer_ptr(&stdout_buffer), len); packet_send(); buffer_consume(&stdout_buffer, len); stdout_bytes += len; } } static void client_alive_check(void) { int channel_id; /* timeout, check to see how many we have had */ if (packet_inc_alive_timeouts() > options.client_alive_count_max) { logit("Timeout, client not responding."); cleanup_exit(255); } /* * send a bogus global/channel request with "wantreply", * we should get back a failure */ if ((channel_id = channel_find_open()) == -1) { packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("keepalive@openssh.com"); packet_put_char(1); /* boolean: want reply */ } else { channel_request_start(channel_id, "keepalive@openssh.com", 1); } packet_send(); } /* * Sleep in select() until we can do something. This will initialize the * select masks. Upon return, the masks will indicate which descriptors * have data or can accept data. Optionally, a maximum time can be specified * for the duration of the wait (0 = infinite). */ static void wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, u_int64_t max_time_milliseconds) { struct timeval tv, *tvp; int ret; time_t minwait_secs = 0; int client_alive_scheduled = 0; int program_alive_scheduled = 0; /* Allocate and update select() masks for channel descriptors. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, &minwait_secs, 0); if (minwait_secs != 0) max_time_milliseconds = MIN(max_time_milliseconds, (u_int)minwait_secs * 1000); /* * if using client_alive, set the max timeout accordingly, * and indicate that this particular timeout was for client * alive by setting the client_alive_scheduled flag. * * this could be randomized somewhat to make traffic * analysis more difficult, but we're not doing it yet. */ if (compat20 && max_time_milliseconds == 0 && options.client_alive_interval) { client_alive_scheduled = 1; max_time_milliseconds = (u_int64_t)options.client_alive_interval * 1000; } if (compat20) { #if 0 /* wrong: bad condition XXX */ if (channel_not_very_much_buffered_data()) #endif FD_SET(connection_in, *readsetp); } else { /* * Read packets from the client unless we have too much * buffered stdin or channel data. */ if (buffer_len(&stdin_buffer) < buffer_high && channel_not_very_much_buffered_data()) FD_SET(connection_in, *readsetp); /* * If there is not too much data already buffered going to * the client, try to get some more data from the program. */ if (packet_not_very_much_data_to_write()) { program_alive_scheduled = child_terminated; if (!fdout_eof) FD_SET(fdout, *readsetp); if (!fderr_eof) FD_SET(fderr, *readsetp); } /* * If we have buffered data, try to write some of that data * to the program. */ if (fdin != -1 && buffer_len(&stdin_buffer) > 0) FD_SET(fdin, *writesetp); } notify_prepare(*readsetp); /* * If we have buffered packet data going to the client, mark that * descriptor. */ if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); /* * If child has terminated and there is enough buffer space to read * from it, then read as much as is available and exit. */ if (child_terminated && packet_not_very_much_data_to_write()) if (max_time_milliseconds == 0 || client_alive_scheduled) max_time_milliseconds = 100; if (max_time_milliseconds == 0) tvp = NULL; else { tv.tv_sec = max_time_milliseconds / 1000; tv.tv_usec = 1000 * (max_time_milliseconds % 1000); tvp = &tv; } /* Wait for something to happen, or the timeout to expire. */ ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); if (ret == -1) { memset(*readsetp, 0, *nallocp); memset(*writesetp, 0, *nallocp); if (errno != EINTR) error("select: %.100s", strerror(errno)); } else { if (ret == 0 && client_alive_scheduled) client_alive_check(); if (!compat20 && program_alive_scheduled && fdin_is_tty) { if (!fdout_eof) FD_SET(fdout, *readsetp); if (!fderr_eof) FD_SET(fderr, *readsetp); } } notify_done(*readsetp); } /* * Processes input from the client and the program. Input data is stored * in buffers and processed later. */ static void process_input(fd_set *readset) { int len; char buf[16384]; /* Read and buffer any input data from the client. */ if (FD_ISSET(connection_in, readset)) { len = read(connection_in, buf, sizeof(buf)); if (len == 0) { verbose("Connection closed by %.100s", get_remote_ipaddr()); connection_closed = 1; if (compat20) return; cleanup_exit(255); } else if (len < 0) { if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { verbose("Read error from remote host " "%.100s: %.100s", get_remote_ipaddr(), strerror(errno)); cleanup_exit(255); } } else { /* Buffer any received data. */ packet_process_incoming(buf, len); } } if (compat20) return; /* Read and buffer any available stdout data from the program. */ if (!fdout_eof && FD_ISSET(fdout, readset)) { errno = 0; len = read(fdout, buf, sizeof(buf)); if (len < 0 && (errno == EINTR || ((errno == EAGAIN || errno == EWOULDBLOCK) && !child_terminated))) { /* do nothing */ #ifndef PTY_ZEROREAD } else if (len <= 0) { #else } else if ((!isatty(fdout) && len <= 0) || (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) { #endif fdout_eof = 1; } else { buffer_append(&stdout_buffer, buf, len); fdout_bytes += len; } } /* Read and buffer any available stderr data from the program. */ if (!fderr_eof && FD_ISSET(fderr, readset)) { errno = 0; len = read(fderr, buf, sizeof(buf)); if (len < 0 && (errno == EINTR || ((errno == EAGAIN || errno == EWOULDBLOCK) && !child_terminated))) { /* do nothing */ #ifndef PTY_ZEROREAD } else if (len <= 0) { #else } else if ((!isatty(fderr) && len <= 0) || (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) { #endif fderr_eof = 1; } else { buffer_append(&stderr_buffer, buf, len); } } } /* * Sends data from internal buffers to client program stdin. */ static void process_output(fd_set *writeset) { struct termios tio; u_char *data; u_int dlen; int len; /* Write buffered data to program stdin. */ if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { data = buffer_ptr(&stdin_buffer); dlen = buffer_len(&stdin_buffer); len = write(fdin, data, dlen); if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) { /* do nothing */ } else if (len <= 0) { if (fdin != fdout) close(fdin); else shutdown(fdin, SHUT_WR); /* We will no longer send. */ fdin = -1; } else { /* Successful write. */ if (fdin_is_tty && dlen >= 1 && data[0] != '\r' && tcgetattr(fdin, &tio) == 0 && !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { /* * Simulate echo to reduce the impact of * traffic analysis */ packet_send_ignore(len); packet_send(); } /* Consume the data from the buffer. */ buffer_consume(&stdin_buffer, len); /* Update the count of bytes written to the program. */ stdin_bytes += len; } } /* Send any buffered packet data to the client. */ if (FD_ISSET(connection_out, writeset)) packet_write_poll(); } /* * Wait until all buffered output has been sent to the client. * This is used when the program terminates. */ static void drain_output(void) { /* Send any buffered stdout data to the client. */ if (buffer_len(&stdout_buffer) > 0) { packet_start(SSH_SMSG_STDOUT_DATA); packet_put_string(buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); packet_send(); /* Update the count of sent bytes. */ stdout_bytes += buffer_len(&stdout_buffer); } /* Send any buffered stderr data to the client. */ if (buffer_len(&stderr_buffer) > 0) { packet_start(SSH_SMSG_STDERR_DATA); packet_put_string(buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); packet_send(); /* Update the count of sent bytes. */ stderr_bytes += buffer_len(&stderr_buffer); } /* Wait until all buffered data has been written to the client. */ packet_write_wait(); } static void process_buffered_input_packets(void) { dispatch_run(DISPATCH_NONBLOCK, NULL, active_state); } /* * Performs the interactive session. This handles data transmission between * the client and the program. Note that the notion of stdin, stdout, and * stderr in this function is sort of reversed: this function writes to * stdin (of the child program), and reads from stdout and stderr (of the * child program). */ void server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) { fd_set *readset = NULL, *writeset = NULL; int max_fd = 0; u_int nalloc = 0; int wait_status; /* Status returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */ int waiting_termination = 0; /* Have displayed waiting close message. */ u_int64_t max_time_milliseconds; u_int previous_stdout_buffer_bytes; u_int stdout_buffer_bytes; int type; debug("Entering interactive session."); /* Initialize the SIGCHLD kludge. */ child_terminated = 0; mysignal(SIGCHLD, sigchld_handler); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } /* Initialize our global variables. */ fdin = fdin_arg; fdout = fdout_arg; fderr = fderr_arg; /* nonblocking IO */ set_nonblock(fdin); set_nonblock(fdout); /* we don't have stderr for interactive terminal sessions, see below */ if (fderr != -1) set_nonblock(fderr); if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) fdin_is_tty = 1; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); notify_setup(); previous_stdout_buffer_bytes = 0; /* Set approximate I/O buffer size. */ if (packet_is_interactive()) buffer_high = 4096; else buffer_high = 64 * 1024; #if 0 /* Initialize max_fd to the maximum of the known file descriptors. */ max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); if (fderr != -1) max_fd = MAX(max_fd, fderr); #endif /* Initialize Initialize buffers. */ buffer_init(&stdin_buffer); buffer_init(&stdout_buffer); buffer_init(&stderr_buffer); /* * If we have no separate fderr (which is the case when we have a pty * - there we cannot make difference between data sent to stdout and * stderr), indicate that we have seen an EOF from stderr. This way * we don't need to check the descriptor everywhere. */ if (fderr == -1) fderr_eof = 1; server_init_dispatch(); /* Main loop of the server for the interactive session mode. */ for (;;) { /* Process buffered packets from the client. */ process_buffered_input_packets(); /* * If we have received eof, and there is no more pending * input data, cause a real eof by closing fdin. */ if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { if (fdin != fdout) close(fdin); else shutdown(fdin, SHUT_WR); /* We will no longer send. */ fdin = -1; } /* Make packets from buffered stderr data to send to the client. */ make_packets_from_stderr_data(); /* * Make packets from buffered stdout data to send to the * client. If there is very little to send, this arranges to * not send them now, but to wait a short while to see if we * are getting more data. This is necessary, as some systems * wake up readers from a pty after each separate character. */ max_time_milliseconds = 0; stdout_buffer_bytes = buffer_len(&stdout_buffer); if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && stdout_buffer_bytes != previous_stdout_buffer_bytes) { /* try again after a while */ max_time_milliseconds = 10; } else { /* Send it now. */ make_packets_from_stdout_data(); } previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); /* Send channel data to the client. */ if (packet_not_very_much_data_to_write()) channel_output_poll(); /* * Bail out of the loop if the program has closed its output * descriptors, and we have no more data to send to the * client, and there is no pending buffered data. */ if (fdout_eof && fderr_eof && !packet_have_data_to_write() && buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { if (!channel_still_open()) break; if (!waiting_termination) { const char *s = "Waiting for forwarded connections to terminate...\r\n"; char *cp; waiting_termination = 1; buffer_append(&stderr_buffer, s, strlen(s)); /* Display list of open channels. */ cp = channel_open_message(); buffer_append(&stderr_buffer, cp, strlen(cp)); free(cp); } } max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); max_fd = MAX(max_fd, fderr); max_fd = MAX(max_fd, notify_pipe[0]); /* Sleep in select() until we can do something. */ wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } /* Process any channel events. */ channel_after_select(readset, writeset); /* Process input from the client and from program stdout/stderr. */ process_input(readset); /* Process output to the client and to program stdin. */ process_output(writeset); } free(readset); free(writeset); /* Cleanup and termination code. */ /* Wait until all output has been sent to the client. */ drain_output(); debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); /* Free and clear the buffers. */ buffer_free(&stdin_buffer); buffer_free(&stdout_buffer); buffer_free(&stderr_buffer); /* Close the file descriptors. */ if (fdout != -1) close(fdout); fdout = -1; fdout_eof = 1; if (fderr != -1) close(fderr); fderr = -1; fderr_eof = 1; if (fdin != -1) close(fdin); fdin = -1; channel_free_all(); /* We no longer want our SIGCHLD handler to be called. */ mysignal(SIGCHLD, SIG_DFL); while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0) if (errno != EINTR) packet_disconnect("wait: %.100s", strerror(errno)); if (wait_pid != pid) error("Strange, wait returned pid %ld, expected %ld", (long)wait_pid, (long)pid); /* Check if it exited normally. */ if (WIFEXITED(wait_status)) { /* Yes, normal exit. Get exit status and send it to the client. */ debug("Command exited with status %d.", WEXITSTATUS(wait_status)); packet_start(SSH_SMSG_EXITSTATUS); packet_put_int(WEXITSTATUS(wait_status)); packet_send(); packet_write_wait(); /* * Wait for exit confirmation. Note that there might be * other packets coming before it; however, the program has * already died so we just ignore them. The client is * supposed to respond with the confirmation when it receives * the exit status. */ do { type = packet_read(); } while (type != SSH_CMSG_EXIT_CONFIRMATION); debug("Received exit confirmation."); return; } /* Check if the program terminated due to a signal. */ if (WIFSIGNALED(wait_status)) packet_disconnect("Command terminated on signal %d.", WTERMSIG(wait_status)); /* Some weird exit cause. Just exit. */ packet_disconnect("wait returned status %04x.", wait_status); /* NOTREACHED */ } static void collect_children(void) { pid_t pid; sigset_t oset, nset; int status; /* block SIGCHLD while we check for dead children */ sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { debug("Received SIGCHLD."); while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) session_close_by_pid(pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL); } void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; int max_fd; u_int nalloc = 0; u_int64_t rekey_timeout_ms = 0; debug("Entering interactive session for SSH2."); mysignal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } notify_setup(); max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, notify_pipe[0]); server_init_dispatch(); for (;;) { process_buffered_input_packets(); if (!ssh_packet_is_rekeying(active_state) && packet_not_very_much_data_to_write()) channel_output_poll(); if (options.rekey_interval > 0 && compat20 && !ssh_packet_is_rekeying(active_state)) rekey_timeout_ms = packet_get_rekey_timeout() * 1000; else rekey_timeout_ms = 0; wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } collect_children(); if (!ssh_packet_is_rekeying(active_state)) channel_after_select(readset, writeset); process_input(readset); if (connection_closed) break; process_output(writeset); } collect_children(); free(readset); free(writeset); /* free all channels, no more reads and writes */ channel_free_all(); /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(NULL); } static int server_input_keep_alive(int type, u_int32_t seq, void *ctxt) { debug("Got %d/%u for keepalive", type, seq); /* * reset timeout, since we got a sane answer from the client. * even if this was generated by something other than * the bogus CHANNEL_REQUEST we send for keepalives. */ packet_set_alive_timeouts(0); return 0; } static int server_input_stdin_data(int type, u_int32_t seq, void *ctxt) { char *data; u_int data_len; /* Stdin data from the client. Append it to the buffer. */ /* Ignore any data if the client has closed stdin. */ if (fdin == -1) return 0; data = packet_get_string(&data_len); packet_check_eom(); buffer_append(&stdin_buffer, data, data_len); explicit_bzero(data, data_len); free(data); return 0; } static int server_input_eof(int type, u_int32_t seq, void *ctxt) { /* * Eof from the client. The stdin descriptor to the * program will be closed when all buffered data has * drained. */ debug("EOF received for stdin."); packet_check_eom(); stdin_eof = 1; return 0; } static int server_input_window_size(int type, u_int32_t seq, void *ctxt) { u_int row = packet_get_int(); u_int col = packet_get_int(); u_int xpixel = packet_get_int(); u_int ypixel = packet_get_int(); debug("Window change received."); packet_check_eom(); if (fdin != -1) pty_change_window_size(fdin, row, col, xpixel, ypixel); return 0; } static Channel * server_request_direct_tcpip(void) { Channel *c = NULL; char *target, *originator; u_short target_port, originator_port; target = packet_get_string(NULL); target_port = packet_get_int(); originator = packet_get_string(NULL); originator_port = packet_get_int(); packet_check_eom(); debug("server_request_direct_tcpip: originator %s port %d, target %s " "port %d", originator, originator_port, target, target_port); /* XXX fine grained permissions */ if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && !no_port_forwarding_flag) { c = channel_connect_to_port(target, target_port, "direct-tcpip", "direct-tcpip"); } else { logit("refused local port forward: " "originator %s port %d, target %s port %d", originator, originator_port, target, target_port); } free(originator); free(target); return c; } static Channel * server_request_direct_streamlocal(void) { Channel *c = NULL; char *target, *originator; u_short originator_port; target = packet_get_string(NULL); originator = packet_get_string(NULL); originator_port = packet_get_int(); packet_check_eom(); debug("server_request_direct_streamlocal: originator %s port %d, target %s", originator, originator_port, target); /* XXX fine grained permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && !no_port_forwarding_flag) { c = channel_connect_to_path(target, "direct-streamlocal@openssh.com", "direct-streamlocal"); } else { logit("refused streamlocal port forward: " "originator %s port %d, target %s", originator, originator_port, target); } free(originator); free(target); return c; } static Channel * server_request_tun(void) { Channel *c = NULL; int mode, tun; int sock; mode = packet_get_int(); switch (mode) { case SSH_TUNMODE_POINTOPOINT: case SSH_TUNMODE_ETHERNET: break; default: packet_send_debug("Unsupported tunnel device mode."); return NULL; } if ((options.permit_tun & mode) == 0) { packet_send_debug("Server has rejected tunnel device " "forwarding"); return NULL; } tun = packet_get_int(); if (forced_tun_device != -1) { if (tun != SSH_TUNID_ANY && forced_tun_device != tun) goto done; tun = forced_tun_device; } sock = tun_open(tun, mode); if (sock < 0) goto done; c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) channel_register_filter(c->self, sys_tun_infilter, sys_tun_outfilter, NULL, NULL); #endif done: if (c == NULL) packet_send_debug("Failed to open the tunnel device."); return c; } static Channel * server_request_session(void) { Channel *c; debug("input_session_request"); packet_check_eom(); if (no_more_sessions) { packet_disconnect("Possible attack: attempt to open a session " "after additional sessions disabled"); } /* * A server session has no fd to read or write until a * CHANNEL_REQUEST for a shell is made, so we set the type to * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all * CHANNEL_REQUEST messages is registered. */ c = channel_new("session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); return NULL; } channel_register_cleanup(c->self, session_close_by_channel, 0); return c; } static int server_input_channel_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; char *ctype; int rchan; u_int rmaxpack, rwindow, len; ctype = packet_get_string(&len); rchan = packet_get_int(); rwindow = packet_get_int(); rmaxpack = packet_get_int(); debug("server_input_channel_open: ctype %s rchan %d win %d max %d", ctype, rchan, rwindow, rmaxpack); if (strcmp(ctype, "session") == 0) { c = server_request_session(); } else if (strcmp(ctype, "direct-tcpip") == 0) { c = server_request_direct_tcpip(); } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { c = server_request_direct_streamlocal(); } else if (strcmp(ctype, "tun@openssh.com") == 0) { c = server_request_tun(); } if (c != NULL) { debug("server_input_channel_open: confirm %s", ctype); c->remote_id = rchan; c->remote_window = rwindow; c->remote_maxpacket = rmaxpack; if (c->type != SSH_CHANNEL_CONNECTING) { packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); packet_put_int(c->remote_id); packet_put_int(c->self); packet_put_int(c->local_window); packet_put_int(c->local_maxpacket); packet_send(); } } else { debug("server_input_channel_open: failure %s", ctype); packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); if (!(datafellows & SSH_BUG_OPENFAILURE)) { packet_put_cstring("open failed"); packet_put_cstring(""); } packet_send(); } free(ctype); return 0; } static int server_input_hostkeys_prove(struct sshbuf **respp) { struct ssh *ssh = active_state; /* XXX */ struct sshbuf *resp = NULL; struct sshbuf *sigbuf = NULL; struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; int r, ndx, success = 0; const u_char *blob; u_char *sig = 0; size_t blen, slen; if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); while (ssh_packet_remaining(ssh) > 0) { sshkey_free(key); key = NULL; if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 || (r = sshkey_from_blob(blob, blen, &key)) != 0) { error("%s: couldn't parse key: %s", __func__, ssh_err(r)); goto out; } /* * Better check that this is actually one of our hostkeys * before attempting to sign anything with it. */ if ((ndx = ssh->kex->host_key_index(key, 1, ssh)) == -1) { error("%s: unknown host %s key", __func__, sshkey_type(key)); goto out; } /* * XXX refactor: make kex->sign just use an index rather * than passing in public and private keys */ if ((key_prv = get_hostkey_by_index(ndx)) == NULL && (key_pub = get_hostkey_public_by_index(ndx, ssh)) == NULL) { error("%s: can't retrieve hostkey %d", __func__, ndx); goto out; } sshbuf_reset(sigbuf); free(sig); sig = NULL; if ((r = sshbuf_put_cstring(sigbuf, "hostkeys-prove-00@openssh.com")) != 0 || (r = sshbuf_put_string(sigbuf, ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0 || (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 || (r = sshbuf_put_string(resp, sig, slen)) != 0) { error("%s: couldn't prepare signature: %s", __func__, ssh_err(r)); goto out; } } /* Success */ *respp = resp; resp = NULL; /* don't free it */ success = 1; out: free(sig); sshbuf_free(resp); sshbuf_free(sigbuf); sshkey_free(key); return success; } static int server_input_global_request(int type, u_int32_t seq, void *ctxt) { char *rtype; int want_reply; int r, success = 0, allocated_listen_port = 0; struct sshbuf *resp = NULL; rtype = packet_get_string(NULL); want_reply = packet_get_char(); debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply); /* -R style forwarding */ if (strcmp(rtype, "tcpip-forward") == 0) { struct passwd *pw; struct Forward fwd; pw = the_authctxt->pw; if (pw == NULL || !the_authctxt->valid) fatal("server_input_global_request: no/invalid user"); memset(&fwd, 0, sizeof(fwd)); fwd.listen_host = packet_get_string(NULL); fwd.listen_port = (u_short)packet_get_int(); debug("server_input_global_request: tcpip-forward listen %s port %d", fwd.listen_host, fwd.listen_port); /* check permissions */ if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || no_port_forwarding_flag || (!want_reply && fwd.listen_port == 0) #ifndef NO_IPPORT_RESERVED_CONCEPT || (fwd.listen_port != 0 && fwd.listen_port < IPPORT_RESERVED && pw->pw_uid != 0) #endif ) { success = 0; packet_send_debug("Server has disabled port forwarding."); } else { /* Start listening on the port */ success = channel_setup_remote_fwd_listener(&fwd, &allocated_listen_port, &options.fwd_opts); } free(fwd.listen_host); if ((resp = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); if (allocated_listen_port != 0 && (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0) fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r)); } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { struct Forward fwd; memset(&fwd, 0, sizeof(fwd)); fwd.listen_host = packet_get_string(NULL); fwd.listen_port = (u_short)packet_get_int(); debug("%s: cancel-tcpip-forward addr %s port %d", __func__, fwd.listen_host, fwd.listen_port); success = channel_cancel_rport_listener(&fwd); free(fwd.listen_host); } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { struct Forward fwd; memset(&fwd, 0, sizeof(fwd)); fwd.listen_path = packet_get_string(NULL); debug("server_input_global_request: streamlocal-forward listen path %s", fwd.listen_path); /* check permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 || no_port_forwarding_flag) { success = 0; packet_send_debug("Server has disabled port forwarding."); } else { /* Start listening on the socket */ success = channel_setup_remote_fwd_listener( &fwd, NULL, &options.fwd_opts); } free(fwd.listen_path); } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) { struct Forward fwd; memset(&fwd, 0, sizeof(fwd)); fwd.listen_path = packet_get_string(NULL); debug("%s: cancel-streamlocal-forward path %s", __func__, fwd.listen_path); success = channel_cancel_rport_listener(&fwd); free(fwd.listen_path); } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { no_more_sessions = 1; success = 1; } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { success = server_input_hostkeys_prove(&resp); } if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); if (success && resp != NULL) ssh_packet_put_raw(active_state, sshbuf_ptr(resp), sshbuf_len(resp)); packet_send(); packet_write_wait(); } free(rtype); sshbuf_free(resp); return 0; } static int server_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c; int id, reply, success = 0; char *rtype; id = packet_get_int(); rtype = packet_get_string(NULL); reply = packet_get_char(); debug("server_input_channel_req: channel %d request %s reply %d", id, rtype, reply); if ((c = channel_lookup(id)) == NULL) packet_disconnect("server_input_channel_req: " "unknown channel %d", id); if (!strcmp(rtype, "eow@openssh.com")) { packet_check_eom(); chan_rcvd_eow(c); } else if ((c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) success = session_input_channel_req(c, rtype); if (reply && !(c->flags & CHAN_CLOSE_SENT)) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); packet_put_int(c->remote_id); packet_send(); } free(rtype); return 0; } static void server_init_dispatch_20(void) { debug("server_init_dispatch_20"); dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); /* client_alive */ dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive); dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); /* rekeying */ dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); } static void server_init_dispatch_13(void) { debug("server_init_dispatch_13"); dispatch_init(NULL); dispatch_set(SSH_CMSG_EOF, &server_input_eof); dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data); dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); } static void server_init_dispatch_15(void) { server_init_dispatch_13(); debug("server_init_dispatch_15"); dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose); } static void server_init_dispatch(void) { if (compat20) server_init_dispatch_20(); else if (compat13) server_init_dispatch_13(); else server_init_dispatch_15(); } openssh-7.2p2/serverloop.h010064400017500001750000000017701267006270000140300ustar00djmdjm/* $OpenBSD: serverloop.h,v 1.6 2006/03/25 22:22:43 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ /* * Performs the interactive session. This handles data transmission between * the client and the program. Note that the notion of stdin, stdout, and * stderr in this function is sort of reversed: this function writes to stdin * (of the child program), and reads from stdout and stderr (of the child * program). */ #ifndef SERVERLOOP_H #define SERVERLOOP_H void server_loop(pid_t, int, int, int); void server_loop2(Authctxt *); #endif openssh-7.2p2/session.c010064400017500001750000002060421267006270000133050ustar00djmdjm/* $OpenBSD: session.c,v 1.280 2016/02/16 03:37:48 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , 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". * * SSH2 support by Markus Friedl. * Copyright (c) 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. */ #include "includes.h" #include #include #ifdef HAVE_SYS_STAT_H # include #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #include #include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" #include "sshpty.h" #include "packet.h" #include "buffer.h" #include "match.h" #include "uidswap.h" #include "compat.h" #include "channels.h" #include "key.h" #include "cipher.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "hostfile.h" #include "auth.h" #include "auth-options.h" #include "authfd.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "servconf.h" #include "sshlogin.h" #include "serverloop.h" #include "canohost.h" #include "session.h" #include "kex.h" #include "monitor_wrap.h" #include "sftp.h" #if defined(KRB5) && defined(USE_AFS) #include #endif #ifdef WITH_SELINUX #include #endif #define IS_INTERNAL_SFTP(c) \ (!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \ (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \ c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \ c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t')) /* func */ Session *session_new(void); void session_set_fds(Session *, int, int, int, int, int); void session_pty_cleanup(Session *); void session_proctitle(Session *); int session_setup_x11fwd(Session *); int do_exec_pty(Session *, const char *); int do_exec_no_pty(Session *, const char *); int do_exec(Session *, const char *); void do_login(Session *, const char *); #ifdef LOGIN_NEEDS_UTMPX static void do_pre_login(Session *s); #endif void do_child(Session *, const char *); void do_motd(void); int check_quietlogin(Session *, const char *); static void do_authenticated1(Authctxt *); static void do_authenticated2(Authctxt *); static int session_pty_req(Session *); /* import */ extern ServerOptions options; extern char *__progname; extern int log_stderr; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; extern void destroy_sensitive_data(void); extern Buffer loginmsg; /* original command from peer. */ const char *original_command = NULL; /* data */ static int sessions_first_unused = -1; static int sessions_nalloc = 0; static Session *sessions = NULL; #define SUBSYSTEM_NONE 0 #define SUBSYSTEM_EXT 1 #define SUBSYSTEM_INT_SFTP 2 #define SUBSYSTEM_INT_SFTP_ERROR 3 #ifdef HAVE_LOGIN_CAP login_cap_t *lc; #endif static int is_child = 0; static int in_chroot = 0; /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; static char *auth_sock_dir = NULL; /* removes the agent forwarding socket */ static void auth_sock_cleanup_proc(struct passwd *pw) { if (auth_sock_name != NULL) { temporarily_use_uid(pw); unlink(auth_sock_name); rmdir(auth_sock_dir); auth_sock_name = NULL; restore_uid(); } } static int auth_input_request_forwarding(struct passwd * pw) { Channel *nc; int sock = -1; if (auth_sock_name != NULL) { error("authentication forwarding requested twice."); return 0; } /* Temporarily drop privileged uid for mkdir/bind. */ temporarily_use_uid(pw); /* Allocate a buffer for the socket name, and format the name. */ auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); /* Create private directory for socket */ if (mkdtemp(auth_sock_dir) == NULL) { packet_send_debug("Agent forwarding disabled: " "mkdtemp() failed: %.100s", strerror(errno)); restore_uid(); free(auth_sock_dir); auth_sock_dir = NULL; goto authsock_err; } xasprintf(&auth_sock_name, "%s/agent.%ld", auth_sock_dir, (long) getpid()); /* Start a Unix listener on auth_sock_name. */ sock = unix_listener(auth_sock_name, SSH_LISTEN_BACKLOG, 0); /* Restore the privileged uid. */ restore_uid(); /* Check for socket/bind/listen failure. */ if (sock < 0) goto authsock_err; /* Allocate a channel for the authentication agent socket. */ nc = channel_new("auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "auth socket", 1); nc->path = xstrdup(auth_sock_name); return 1; authsock_err: free(auth_sock_name); if (auth_sock_dir != NULL) { rmdir(auth_sock_dir); free(auth_sock_dir); } if (sock != -1) close(sock); auth_sock_name = NULL; auth_sock_dir = NULL; return 0; } static void display_loginmsg(void) { if (buffer_len(&loginmsg) > 0) { buffer_append(&loginmsg, "\0", 1); printf("%s", (char *)buffer_ptr(&loginmsg)); buffer_clear(&loginmsg); } } void do_authenticated(Authctxt *authctxt) { setproctitle("%s", authctxt->pw->pw_name); /* setup the channel layer */ /* XXX - streamlocal? */ if (no_port_forwarding_flag || (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) channel_disable_adm_local_opens(); else channel_permit_all_opens(); auth_debug_send(); if (compat20) do_authenticated2(authctxt); else do_authenticated1(authctxt); do_cleanup(authctxt); } /* Check untrusted xauth strings for metacharacters */ static int xauth_valid_string(const char *s) { size_t i; for (i = 0; s[i] != '\0'; i++) { if (!isalnum((u_char)s[i]) && s[i] != '.' && s[i] != ':' && s[i] != '/' && s[i] != '-' && s[i] != '_') return 0; } return 1; } /* * Prepares for an interactive session. This is called after the user has * been successfully authenticated. During this message exchange, pseudo * terminals are allocated, X11, TCP/IP, and authentication agent forwardings * are requested, etc. */ static void do_authenticated1(Authctxt *authctxt) { Session *s; char *command; int success, type, screen_flag; int enable_compression_after_reply = 0; u_int proto_len, data_len, dlen, compression_level = 0; s = session_new(); if (s == NULL) { error("no more sessions"); return; } s->authctxt = authctxt; s->pw = authctxt->pw; /* * We stay in this loop until the client requests to execute a shell * or a command. */ for (;;) { success = 0; /* Get a packet from the client. */ type = packet_read(); /* Process the packet. */ switch (type) { case SSH_CMSG_REQUEST_COMPRESSION: compression_level = packet_get_int(); packet_check_eom(); if (compression_level < 1 || compression_level > 9) { packet_send_debug("Received invalid compression level %d.", compression_level); break; } if (options.compression == COMP_NONE) { debug2("compression disabled"); break; } /* Enable compression after we have responded with SUCCESS. */ enable_compression_after_reply = 1; success = 1; break; case SSH_CMSG_REQUEST_PTY: success = session_pty_req(s); break; case SSH_CMSG_X11_REQUEST_FORWARDING: s->auth_proto = packet_get_string(&proto_len); s->auth_data = packet_get_string(&data_len); screen_flag = packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER; debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag); if (packet_remaining() == 4) { if (!screen_flag) debug2("Buggy client: " "X11 screen flag missing"); s->screen = packet_get_int(); } else { s->screen = 0; } packet_check_eom(); if (xauth_valid_string(s->auth_proto) && xauth_valid_string(s->auth_data)) success = session_setup_x11fwd(s); else { success = 0; error("Invalid X11 forwarding data"); } if (!success) { free(s->auth_proto); free(s->auth_data); s->auth_proto = NULL; s->auth_data = NULL; } break; case SSH_CMSG_AGENT_REQUEST_FORWARDING: if (!options.allow_agent_forwarding || no_agent_forwarding_flag || compat13) { debug("Authentication agent forwarding not permitted for this authentication."); break; } debug("Received authentication agent forwarding request."); success = auth_input_request_forwarding(s->pw); break; case SSH_CMSG_PORT_FORWARD_REQUEST: if (no_port_forwarding_flag) { debug("Port forwarding not permitted for this authentication."); break; } if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) { debug("Port forwarding not permitted."); break; } debug("Received TCP/IP port forwarding request."); if (channel_input_port_forward_request(s->pw->pw_uid == 0, &options.fwd_opts) < 0) { debug("Port forwarding failed."); break; } success = 1; break; case SSH_CMSG_MAX_PACKET_SIZE: if (packet_set_maxsize(packet_get_int()) > 0) success = 1; break; case SSH_CMSG_EXEC_SHELL: case SSH_CMSG_EXEC_CMD: if (type == SSH_CMSG_EXEC_CMD) { command = packet_get_string(&dlen); debug("Exec command '%.500s'", command); if (do_exec(s, command) != 0) packet_disconnect( "command execution failed"); free(command); } else { if (do_exec(s, NULL) != 0) packet_disconnect( "shell execution failed"); } packet_check_eom(); session_close(s); return; default: /* * Any unknown messages in this phase are ignored, * and a failure message is returned. */ logit("Unknown packet type received after authentication: %d", type); } packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); /* Enable compression now that we have replied if appropriate. */ if (enable_compression_after_reply) { enable_compression_after_reply = 0; packet_start_compression(compression_level); } } } #define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This * will call do_child from the child, and server_loop from the parent after * setting up file descriptors and such. */ int do_exec_no_pty(Session *s, const char *command) { pid_t pid; #ifdef USE_PIPES int pin[2], pout[2], perr[2]; if (s == NULL) fatal("do_exec_no_pty: no session"); /* Allocate pipes for communicating with the program. */ if (pipe(pin) < 0) { error("%s: pipe in: %.100s", __func__, strerror(errno)); return -1; } if (pipe(pout) < 0) { error("%s: pipe out: %.100s", __func__, strerror(errno)); close(pin[0]); close(pin[1]); return -1; } if (pipe(perr) < 0) { error("%s: pipe err: %.100s", __func__, strerror(errno)); close(pin[0]); close(pin[1]); close(pout[0]); close(pout[1]); return -1; } #else int inout[2], err[2]; if (s == NULL) fatal("do_exec_no_pty: no session"); /* Uses socket pairs to communicate with the program. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) { error("%s: socketpair #1: %.100s", __func__, strerror(errno)); return -1; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) { error("%s: socketpair #2: %.100s", __func__, strerror(errno)); close(inout[0]); close(inout[1]); return -1; } #endif session_proctitle(s); /* Fork the child. */ switch ((pid = fork())) { case -1: error("%s: fork: %.100s", __func__, strerror(errno)); #ifdef USE_PIPES close(pin[0]); close(pin[1]); close(pout[0]); close(pout[1]); close(perr[0]); close(perr[1]); #else close(inout[0]); close(inout[1]); close(err[0]); close(err[1]); #endif return -1; case 0: is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* * Create a new session and process group since the 4.4BSD * setlogin() affects the entire process group. */ if (setsid() < 0) error("setsid failed: %.100s", strerror(errno)); #ifdef USE_PIPES /* * Redirect stdin. We close the parent side of the socket * pair, and make the child side the standard input. */ close(pin[1]); if (dup2(pin[0], 0) < 0) perror("dup2 stdin"); close(pin[0]); /* Redirect stdout. */ close(pout[0]); if (dup2(pout[1], 1) < 0) perror("dup2 stdout"); close(pout[1]); /* Redirect stderr. */ close(perr[0]); if (dup2(perr[1], 2) < 0) perror("dup2 stderr"); close(perr[1]); #else /* * Redirect stdin, stdout, and stderr. Stdin and stdout will * use the same socket, as some programs (particularly rdist) * seem to depend on it. */ close(inout[1]); close(err[1]); if (dup2(inout[0], 0) < 0) /* stdin */ perror("dup2 stdin"); if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ perror("dup2 stdout"); close(inout[0]); if (dup2(err[0], 2) < 0) /* stderr */ perror("dup2 stderr"); close(err[0]); #endif #ifdef _UNICOS cray_init_job(s->pw); /* set up cray jid and tmpdir */ #endif /* Do processing for the child (exec command etc). */ do_child(s, command); /* NOTREACHED */ default: break; } #ifdef _UNICOS signal(WJSIGNAL, cray_job_termination_handler); #endif /* _UNICOS */ #ifdef HAVE_CYGWIN cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); #endif s->pid = pid; /* Set interactive/non-interactive mode. */ packet_set_interactive(s->display != NULL, options.ip_qos_interactive, options.ip_qos_bulk); /* * Clear loginmsg, since it's the child's responsibility to display * it to the user, otherwise multiple sessions may accumulate * multiple copies of the login messages. */ buffer_clear(&loginmsg); #ifdef USE_PIPES /* We are the parent. Close the child sides of the pipes. */ close(pin[0]); close(pout[1]); close(perr[1]); if (compat20) { session_set_fds(s, pin[1], pout[0], perr[0], s->is_subsystem, 0); } else { /* Enter the interactive session. */ server_loop(pid, pin[1], pout[0], perr[0]); /* server_loop has closed pin[1], pout[0], and perr[0]. */ } #else /* We are the parent. Close the child sides of the socket pairs. */ close(inout[0]); close(err[0]); /* * Enter the interactive session. Note: server_loop must be able to * handle the case that fdin and fdout are the same. */ if (compat20) { session_set_fds(s, inout[1], inout[1], err[1], s->is_subsystem, 0); } else { server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ } #endif return 0; } /* * This is called to fork and execute a command when we have a tty. This * will call do_child from the child, and server_loop from the parent after * setting up file descriptors, controlling tty, updating wtmp, utmp, * lastlog, and other such operations. */ int do_exec_pty(Session *s, const char *command) { int fdout, ptyfd, ttyfd, ptymaster; pid_t pid; if (s == NULL) fatal("do_exec_pty: no session"); ptyfd = s->ptyfd; ttyfd = s->ttyfd; /* * Create another descriptor of the pty master side for use as the * standard input. We could use the original descriptor, but this * simplifies code in server_loop. The descriptor is bidirectional. * Do this before forking (and cleanup in the child) so as to * detect and gracefully fail out-of-fd conditions. */ if ((fdout = dup(ptyfd)) < 0) { error("%s: dup #1: %s", __func__, strerror(errno)); close(ttyfd); close(ptyfd); return -1; } /* we keep a reference to the pty master */ if ((ptymaster = dup(ptyfd)) < 0) { error("%s: dup #2: %s", __func__, strerror(errno)); close(ttyfd); close(ptyfd); close(fdout); return -1; } /* Fork the child. */ switch ((pid = fork())) { case -1: error("%s: fork: %.100s", __func__, strerror(errno)); close(fdout); close(ptymaster); close(ttyfd); close(ptyfd); return -1; case 0: is_child = 1; close(fdout); close(ptymaster); /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Close the master side of the pseudo tty. */ close(ptyfd); /* Make the pseudo tty our controlling tty. */ pty_make_controlling_tty(&ttyfd, s->tty); /* Redirect stdin/stdout/stderr from the pseudo tty. */ if (dup2(ttyfd, 0) < 0) error("dup2 stdin: %s", strerror(errno)); if (dup2(ttyfd, 1) < 0) error("dup2 stdout: %s", strerror(errno)); if (dup2(ttyfd, 2) < 0) error("dup2 stderr: %s", strerror(errno)); /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA if (!(options.use_login && command == NULL)) { #ifdef _UNICOS cray_init_job(s->pw); /* set up cray jid and tmpdir */ #endif /* _UNICOS */ do_login(s, command); } # ifdef LOGIN_NEEDS_UTMPX else do_pre_login(s); # endif #endif /* * Do common processing for the child, such as execing * the command. */ do_child(s, command); /* NOTREACHED */ default: break; } #ifdef _UNICOS signal(WJSIGNAL, cray_job_termination_handler); #endif /* _UNICOS */ #ifdef HAVE_CYGWIN cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); #endif s->pid = pid; /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); /* Enter interactive session. */ s->ptymaster = ptymaster; packet_set_interactive(1, options.ip_qos_interactive, options.ip_qos_bulk); if (compat20) { session_set_fds(s, ptyfd, fdout, -1, 1, 1); } else { server_loop(pid, ptyfd, fdout, -1); /* server_loop _has_ closed ptyfd and fdout. */ } return 0; } #ifdef LOGIN_NEEDS_UTMPX static void do_pre_login(Session *s) { socklen_t fromlen; struct sockaddr_storage from; pid_t pid = getpid(); /* * Get IP address of client. If the connection is not a socket, let * the address be 0.0.0.0. */ memset(&from, 0, sizeof(from)); fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } } record_utmp_only(pid, s->tty, s->pw->pw_name, get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } #endif /* * This is called to fork and execute a command. If another command is * to be forced, execute that instead. */ int do_exec(Session *s, const char *command) { int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; forced = "(config)"; } else if (forced_command) { original_command = command; command = forced_command; forced = "(key-option)"; } if (forced != NULL) { if (IS_INTERNAL_SFTP(command)) { s->is_subsystem = s->is_subsystem ? SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; snprintf(session_type, sizeof(session_type), "forced-command %s '%.900s'", forced, command); } else if (s->is_subsystem) { snprintf(session_type, sizeof(session_type), "subsystem '%.900s'", s->subsys); } else if (command == NULL) { snprintf(session_type, sizeof(session_type), "shell"); } else { /* NB. we don't log unforced commands to preserve privacy */ snprintf(session_type, sizeof(session_type), "command"); } if (s->ttyfd != -1) { tty = s->tty; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; } verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", tty == NULL ? "" : tty, s->pw->pw_name, get_remote_ipaddr(), get_remote_port(), s->self); #ifdef SSH_AUDIT_EVENTS if (command != NULL) PRIVSEP(audit_run_command(command)); else if (s->ttyfd == -1) { char *shell = s->pw->pw_shell; if (shell[0] == '\0') /* empty shell means /bin/sh */ shell =_PATH_BSHELL; PRIVSEP(audit_run_command(shell)); } #endif if (s->ttyfd != -1) ret = do_exec_pty(s, command); else ret = do_exec_no_pty(s, command); original_command = NULL; /* * Clear loginmsg: it's the child's responsibility to display * it to the user, otherwise multiple sessions may accumulate * multiple copies of the login messages. */ buffer_clear(&loginmsg); return ret; } /* administrative, login(1)-like work */ void do_login(Session *s, const char *command) { socklen_t fromlen; struct sockaddr_storage from; struct passwd * pw = s->pw; pid_t pid = getpid(); /* * Get IP address of client. If the connection is not a socket, let * the address be 0.0.0.0. */ memset(&from, 0, sizeof(from)); fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } } /* Record that there was a login on that tty from the remote host. */ if (!use_privsep) record_login(pid, s->tty, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); #ifdef USE_PAM /* * If password change is needed, do it now. * This needs to occur before the ~/.hushlogin check. */ if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) { display_loginmsg(); do_pam_chauthtok(); s->authctxt->force_pwchange = 0; /* XXX - signal [net] parent to enable forwardings */ } #endif if (check_quietlogin(s, command)) return; display_loginmsg(); do_motd(); } /* * Display the message of the day. */ void do_motd(void) { FILE *f; char buf[256]; if (options.print_motd) { #ifdef HAVE_LOGIN_CAP f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", "/etc/motd"), "r"); #else f = fopen("/etc/motd", "r"); #endif if (f) { while (fgets(buf, sizeof(buf), f)) fputs(buf, stdout); fclose(f); } } } /* * Check for quiet login, either .hushlogin or command given. */ int check_quietlogin(Session *s, const char *command) { char buf[256]; struct passwd *pw = s->pw; struct stat st; /* Return 1 if .hushlogin exists or a command given. */ if (command != NULL) return 1; snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); #ifdef HAVE_LOGIN_CAP if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) return 1; #else if (stat(buf, &st) >= 0) return 1; #endif return 0; } /* * Sets the value of the given variable in the environment. If the variable * already exists, its value is overridden. */ void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *value) { char **env; u_int envsize; u_int i, namelen; if (strchr(name, '=') != NULL) { error("Invalid environment variable \"%.100s\"", name); return; } /* * If we're passed an uninitialized list, allocate a single null * entry before continuing. */ if (*envp == NULL && *envsizep == 0) { *envp = xmalloc(sizeof(char *)); *envp[0] = NULL; *envsizep = 1; } /* * Find the slot where the value should be stored. If the variable * already exists, we reuse the slot; otherwise we append a new slot * at the end of the array, expanding if necessary. */ env = *envp; namelen = strlen(name); for (i = 0; env[i]; i++) if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') break; if (env[i]) { /* Reuse the slot. */ free(env[i]); } else { /* New variable. Expand if necessary. */ envsize = *envsizep; if (i >= envsize - 1) { if (envsize >= 1000) fatal("child_set_env: too many env vars"); envsize += 50; env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); *envsizep = envsize; } /* Need to set the NULL pointer at end of array beyond the new slot. */ env[i + 1] = NULL; } /* Allocate space and format the variable in the appropriate slot. */ env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); } /* * Reads environment variables from the given file and adds/overrides them * into the environment. If the file does not exist, this does nothing. * Otherwise, it must consist of empty lines, comments (line starts with '#') * and assignments of the form name=value. No other forms are allowed. */ static void read_environment_file(char ***env, u_int *envsize, const char *filename) { FILE *f; char buf[4096]; char *cp, *value; u_int lineno = 0; f = fopen(filename, "r"); if (!f) return; while (fgets(buf, sizeof(buf), f)) { if (++lineno > 1000) fatal("Too many lines in environment file %s", filename); for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) ; if (!*cp || *cp == '#' || *cp == '\n') continue; cp[strcspn(cp, "\n")] = '\0'; value = strchr(cp, '='); if (value == NULL) { fprintf(stderr, "Bad line %u in %.100s\n", lineno, filename); continue; } /* * Replace the equals sign by nul, and advance value to * the value string. */ *value = '\0'; value++; child_set_env(env, envsize, cp, value); } fclose(f); } #ifdef HAVE_ETC_DEFAULT_LOGIN /* * Return named variable from specified environment, or NULL if not present. */ static char * child_get_env(char **env, const char *name) { int i; size_t len; len = strlen(name); for (i=0; env[i] != NULL; i++) if (strncmp(name, env[i], len) == 0 && env[i][len] == '=') return(env[i] + len + 1); return NULL; } /* * Read /etc/default/login. * We pick up the PATH (or SUPATH for root) and UMASK. */ static void read_etc_default_login(char ***env, u_int *envsize, uid_t uid) { char **tmpenv = NULL, *var; u_int i, tmpenvsize = 0; u_long mask; /* * We don't want to copy the whole file to the child's environment, * so we use a temporary environment and copy the variables we're * interested in. */ read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login"); if (tmpenv == NULL) return; if (uid == 0) var = child_get_env(tmpenv, "SUPATH"); else var = child_get_env(tmpenv, "PATH"); if (var != NULL) child_set_env(env, envsize, "PATH", var); if ((var = child_get_env(tmpenv, "UMASK")) != NULL) if (sscanf(var, "%5lo", &mask) == 1) umask((mode_t)mask); for (i = 0; tmpenv[i] != NULL; i++) free(tmpenv[i]); free(tmpenv); } #endif /* HAVE_ETC_DEFAULT_LOGIN */ void copy_environment(char **source, char ***env, u_int *envsize) { char *var_name, *var_val; int i; if (source == NULL) return; for(i = 0; source[i] != NULL; i++) { var_name = xstrdup(source[i]); if ((var_val = strstr(var_name, "=")) == NULL) { free(var_name); continue; } *var_val++ = '\0'; debug3("Copy environment: %s=%s", var_name, var_val); child_set_env(env, envsize, var_name, var_val); free(var_name); } } static char ** do_setup_env(Session *s, const char *shell) { char buf[256]; u_int i, envsize; char **env, *laddr; struct passwd *pw = s->pw; #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) char *path = NULL; #endif /* Initialize the environment. */ envsize = 100; env = xcalloc(envsize, sizeof(char *)); env[0] = NULL; #ifdef HAVE_CYGWIN /* * The Windows environment contains some setting which are * important for a running system. They must not be dropped. */ { char **p; p = fetch_windows_environment(); copy_environment(p, &env, &envsize); free_windows_environment(p); } #endif #ifdef GSSAPI /* Allow any GSSAPI methods that we've used to alter * the childs environment as they see fit */ ssh_gssapi_do_child(&env, &envsize); #endif if (!options.use_login) { /* Set basic environment. */ for (i = 0; i < s->num_env; i++) child_set_env(&env, &envsize, s->env[i].name, s->env[i].val); child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); #ifdef _AIX child_set_env(&env, &envsize, "LOGIN", pw->pw_name); #endif child_set_env(&env, &envsize, "HOME", pw->pw_dir); #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); else child_set_env(&env, &envsize, "PATH", getenv("PATH")); #else /* HAVE_LOGIN_CAP */ # ifndef HAVE_CYGWIN /* * There's no standard path on Windows. The path contains * important components pointing to the system directories, * needed for loading shared libraries. So the path better * remains intact here. */ # ifdef HAVE_ETC_DEFAULT_LOGIN read_etc_default_login(&env, &envsize, pw->pw_uid); path = child_get_env(env, "PATH"); # endif /* HAVE_ETC_DEFAULT_LOGIN */ if (path == NULL || *path == '\0') { child_set_env(&env, &envsize, "PATH", s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); } # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); child_set_env(&env, &envsize, "MAIL", buf); /* Normal systems set SHELL by default. */ child_set_env(&env, &envsize, "SHELL", shell); } if (getenv("TZ")) child_set_env(&env, &envsize, "TZ", getenv("TZ")); /* Set custom environment options from RSA authentication. */ if (!options.use_login) { while (custom_environment) { struct envstring *ce = custom_environment; char *str = ce->s; for (i = 0; str[i] != '=' && str[i]; i++) ; if (str[i] == '=') { str[i] = 0; child_set_env(&env, &envsize, str, str + i + 1); } custom_environment = ce->next; free(ce->s); free(ce); } } /* SSH_CLIENT deprecated */ snprintf(buf, sizeof buf, "%.50s %d %d", get_remote_ipaddr(), get_remote_port(), get_local_port()); child_set_env(&env, &envsize, "SSH_CLIENT", buf); laddr = get_local_ipaddr(packet_get_connection_in()); snprintf(buf, sizeof buf, "%.50s %d %.50s %d", get_remote_ipaddr(), get_remote_port(), laddr, get_local_port()); free(laddr); child_set_env(&env, &envsize, "SSH_CONNECTION", buf); if (s->ttyfd != -1) child_set_env(&env, &envsize, "SSH_TTY", s->tty); if (s->term) child_set_env(&env, &envsize, "TERM", s->term); if (s->display) child_set_env(&env, &envsize, "DISPLAY", s->display); if (original_command) child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", original_command); #ifdef _UNICOS if (cray_tmpdir[0] != '\0') child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); #endif /* _UNICOS */ /* * Since we clear KRB5CCNAME at startup, if it's set now then it * must have been set by a native authentication method (eg AIX or * SIA), so copy it to the child. */ { char *cp; if ((cp = getenv("KRB5CCNAME")) != NULL) child_set_env(&env, &envsize, "KRB5CCNAME", cp); } #ifdef _AIX { char *cp; if ((cp = getenv("AUTHSTATE")) != NULL) child_set_env(&env, &envsize, "AUTHSTATE", cp); read_environment_file(&env, &envsize, "/etc/environment"); } #endif #ifdef KRB5 if (s->authctxt->krb5_ccname) child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif #ifdef USE_PAM /* * Pull in any environment variables that may have * been set by PAM. */ if (options.use_pam) { char **p; p = fetch_pam_child_environment(); copy_environment(p, &env, &envsize); free_pam_environment(p); p = fetch_pam_environment(); copy_environment(p, &env, &envsize); free_pam_environment(p); } #endif /* USE_PAM */ if (auth_sock_name != NULL) child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, auth_sock_name); /* read $HOME/.ssh/environment. */ if (options.permit_user_env && !options.use_login) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); read_environment_file(&env, &envsize, buf); } if (debug_flag) { /* dump the environment */ fprintf(stderr, "Environment:\n"); for (i = 0; env[i]; i++) fprintf(stderr, " %.200s\n", env[i]); } return env; } /* * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found * first in this order). */ static void do_rc_files(Session *s, const char *shell) { FILE *f = NULL; char cmd[1024]; int do_xauth; struct stat st; do_xauth = s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */ if (!s->is_subsystem && options.adm_forced_command == NULL && !no_user_rc && options.permit_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) { snprintf(cmd, sizeof cmd, "%s -c '%s %s'", shell, _PATH_BSHELL, _PATH_SSH_USER_RC); if (debug_flag) fprintf(stderr, "Running %s\n", cmd); f = popen(cmd, "w"); if (f) { if (do_xauth) fprintf(f, "%s %s\n", s->auth_proto, s->auth_data); pclose(f); } else fprintf(stderr, "Could not run %s\n", _PATH_SSH_USER_RC); } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) { if (debug_flag) fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, _PATH_SSH_SYSTEM_RC); f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w"); if (f) { if (do_xauth) fprintf(f, "%s %s\n", s->auth_proto, s->auth_data); pclose(f); } else fprintf(stderr, "Could not run %s\n", _PATH_SSH_SYSTEM_RC); } else if (do_xauth && options.xauth_location != NULL) { /* Add authority data to .Xauthority if appropriate. */ if (debug_flag) { fprintf(stderr, "Running %.500s remove %.100s\n", options.xauth_location, s->auth_display); fprintf(stderr, "%.500s add %.100s %.100s %.100s\n", options.xauth_location, s->auth_display, s->auth_proto, s->auth_data); } snprintf(cmd, sizeof cmd, "%s -q -", options.xauth_location); f = popen(cmd, "w"); if (f) { fprintf(f, "remove %s\n", s->auth_display); fprintf(f, "add %s %s %s\n", s->auth_display, s->auth_proto, s->auth_data); pclose(f); } else { fprintf(stderr, "Could not run %s\n", cmd); } } } static void do_nologin(struct passwd *pw) { FILE *f = NULL; char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; struct stat sb; #ifdef HAVE_LOGIN_CAP if (login_getcapbool(lc, "ignorenologin", 0) || pw->pw_uid == 0) return; nl = login_getcapstr(lc, "nologin", def_nl, def_nl); #else if (pw->pw_uid == 0) return; nl = def_nl; #endif if (stat(nl, &sb) == -1) { if (nl != def_nl) free(nl); return; } /* /etc/nologin exists. Print its contents if we can and exit. */ logit("User %.100s not allowed because %s exists", pw->pw_name, nl); if ((f = fopen(nl, "r")) != NULL) { while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); fclose(f); } exit(254); } /* * Chroot into a directory after checking it for safety: all path components * must be root-owned directories with strict permissions. */ static void safely_chroot(const char *path, uid_t uid) { const char *cp; char component[PATH_MAX]; struct stat st; if (*path != '/') fatal("chroot path does not begin at root"); if (strlen(path) >= sizeof(component)) fatal("chroot path too long"); /* * Descend the path, checking that each component is a * root-owned directory with strict permissions. */ for (cp = path; cp != NULL;) { if ((cp = strchr(cp, '/')) == NULL) strlcpy(component, path, sizeof(component)); else { cp++; memcpy(component, path, cp - path); component[cp - path] = '\0'; } debug3("%s: checking '%s'", __func__, component); if (stat(component, &st) != 0) fatal("%s: stat(\"%s\"): %s", __func__, component, strerror(errno)); if (st.st_uid != 0 || (st.st_mode & 022) != 0) fatal("bad ownership or modes for chroot " "directory %s\"%s\"", cp == NULL ? "" : "component ", component); if (!S_ISDIR(st.st_mode)) fatal("chroot path %s\"%s\" is not a directory", cp == NULL ? "" : "component ", component); } if (chdir(path) == -1) fatal("Unable to chdir to chroot path \"%s\": " "%s", path, strerror(errno)); if (chroot(path) == -1) fatal("chroot(\"%s\"): %s", path, strerror(errno)); if (chdir("/") == -1) fatal("%s: chdir(/) after chroot: %s", __func__, strerror(errno)); verbose("Changed root directory to \"%s\"", path); } /* Set login name, uid, gid, and groups. */ void do_setusercontext(struct passwd *pw) { char *chroot_path, *tmp; platform_setusercontext(pw); if (platform_privileged_uidswap()) { #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { perror("unable to set user context"); exit(1); } #else if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); } /* Initialize the group list. */ if (initgroups(pw->pw_name, pw->pw_gid) < 0) { perror("initgroups"); exit(1); } endgrent(); #endif platform_setusercontext_post_groups(pw); if (!in_chroot && options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { tmp = tilde_expand_filename(options.chroot_directory, pw->pw_uid); chroot_path = percent_expand(tmp, "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); /* Make sure we don't attempt to chroot again */ free(options.chroot_directory); options.chroot_directory = NULL; in_chroot = 1; } #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { perror("unable to set user context (setuser)"); exit(1); } /* * FreeBSD's setusercontext() will not apply the user's * own umask setting unless running with the user's UID. */ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK); #else # ifdef USE_LIBIAF /* * In a chroot environment, the set_id() will always fail; * typically because of the lack of necessary authentication * services and runtime such as ./usr/lib/libiaf.so, * ./usr/lib/libpam.so.1, and ./etc/passwd We skip it in the * internal sftp chroot case. We'll lose auditing and ACLs but * permanently_set_uid will take care of the rest. */ if (!in_chroot && set_id(pw->pw_name) != 0) fatal("set_id(%s) Failed", pw->pw_name); # endif /* USE_LIBIAF */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif } else if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { fatal("server lacks privileges to chroot to ChrootDirectory"); } if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); } static void do_pwchange(Session *s) { fflush(NULL); fprintf(stderr, "WARNING: Your password has expired.\n"); if (s->ttyfd != -1) { fprintf(stderr, "You must change your password now and login again!\n"); #ifdef WITH_SELINUX setexeccon(NULL); #endif #ifdef PASSWD_NEEDS_USERNAME execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name, (char *)NULL); #else execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL); #endif perror("passwd"); } else { fprintf(stderr, "Password change required but no TTY available.\n"); } exit(1); } static void launch_login(struct passwd *pw, const char *hostname) { /* Launch login(1). */ execl(LOGIN_PROGRAM, "login", "-h", hostname, #ifdef xxxLOGIN_NEEDS_TERM (s->term ? s->term : "unknown"), #endif /* LOGIN_NEEDS_TERM */ #ifdef LOGIN_NO_ENDOPT "-p", "-f", pw->pw_name, (char *)NULL); #else "-p", "-f", "--", pw->pw_name, (char *)NULL); #endif /* Login couldn't be executed, die. */ perror("login"); exit(1); } static void child_close_fds(void) { extern int auth_sock; if (auth_sock != -1) { close(auth_sock); auth_sock = -1; } if (packet_get_connection_in() == packet_get_connection_out()) close(packet_get_connection_in()); else { close(packet_get_connection_in()); close(packet_get_connection_out()); } /* * Close all descriptors related to channels. They will still remain * open in the parent. */ /* XXX better use close-on-exec? -markus */ channel_close_all(); /* * Close any extra file descriptors. Note that there may still be * descriptors left by system functions. They will be closed later. */ endpwent(); /* * Close any extra open file descriptors so that we don't have them * hanging around in clients. Note that we want to do this after * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. */ closefrom(STDERR_FILENO + 1); } /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group * ids, and executing the command or shell. */ #define ARGV_MAX 10 void do_child(Session *s, const char *command) { extern char **environ; char **env; char *argv[ARGV_MAX]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; int r = 0; /* remove hostkey from the child's memory */ destroy_sensitive_data(); /* Force a password change */ if (s->authctxt->force_pwchange) { do_setusercontext(pw); child_close_fds(); do_pwchange(s); exit(1); } /* login(1) is only called if we execute the login shell */ if (options.use_login && command != NULL) options.use_login = 0; #ifdef _UNICOS cray_setup(pw->pw_uid, pw->pw_name, command); #endif /* _UNICOS */ /* * Login(1) does this as well, and it needs uid 0 for the "-h" * switch, so we let login(1) to this for us. */ if (!options.use_login) { #ifdef HAVE_OSF_SIA session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); if (!check_quietlogin(s, command)) do_motd(); #else /* HAVE_OSF_SIA */ /* When PAM is enabled we rely on it to do the nologin check */ if (!options.use_pam) do_nologin(pw); do_setusercontext(pw); /* * PAM session modules in do_setusercontext may have * generated messages, so if this in an interactive * login then display them too. */ if (!check_quietlogin(s, command)) display_loginmsg(); #endif /* HAVE_OSF_SIA */ } #ifdef USE_PAM if (options.use_pam && !options.use_login && !is_pam_session_open()) { debug3("PAM session not opened, exiting"); display_loginmsg(); exit(254); } #endif /* * 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; /* * Make sure $SHELL points to the shell from the password file, * even if shell is overridden from login.conf */ env = do_setup_env(s, shell); #ifdef HAVE_LOGIN_CAP shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); #endif /* we have to stash the hostname before we close our socket. */ if (options.use_login) hostname = get_remote_name_or_ip(utmp_len, options.use_dns); /* * Close the connection descriptors; note that this is the child, and * the server will still have the socket open, and it is important * that we do not shutdown it. Note that the descriptors cannot be * closed before building the environment, as we call * get_remote_ipaddr there. */ child_close_fds(); /* * Must take new environment into use so that .ssh/rc, * /etc/ssh/sshrc and xauth are run in the proper environment. */ environ = env; #if defined(KRB5) && defined(USE_AFS) /* * At this point, we check to see if AFS is active and if we have * a valid Kerberos 5 TGT. If so, it seems like a good idea to see * if we can (and need to) extend the ticket into an AFS token. If * we don't do this, we run into potential problems if the user's * home directory is in AFS and it's not world-readable. */ if (options.kerberos_get_afs_token && k_hasafs() && (s->authctxt->krb5_ctx != NULL)) { char cell[64]; debug("Getting AFS token"); k_setpag(); if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) krb5_afslog(s->authctxt->krb5_ctx, s->authctxt->krb5_fwd_ccache, cell, NULL); krb5_afslog_home(s->authctxt->krb5_ctx, s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir); } #endif /* Change current directory to the user's home directory. */ if (chdir(pw->pw_dir) < 0) { /* Suppress missing homedir warning for chroot case */ #ifdef HAVE_LOGIN_CAP r = login_getcapbool(lc, "requirehome", 0); #endif if (r || !in_chroot) { fprintf(stderr, "Could not chdir to home " "directory %s: %s\n", pw->pw_dir, strerror(errno)); } if (r) exit(1); } closefrom(STDERR_FILENO + 1); if (!options.use_login) do_rc_files(s, shell); /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { printf("This service allows sftp connections only.\n"); fflush(NULL); exit(1); } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { extern int optind, optreset; int i; char *p, *args; setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME); args = xstrdup(command ? command : "sftp-server"); for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) if (i < ARGV_MAX - 1) argv[i++] = p; argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; #ifdef WITH_SELINUX ssh_selinux_change_context("sftpd_t"); #endif exit(sftp_server_main(i, argv, s->pw)); } fflush(NULL); if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ } /* Get the last component of the shell name. */ if ((shell0 = strrchr(shell, '/')) != NULL) shell0++; else shell0 = shell; /* * If we have no command, execute the shell. In this case, the shell * name to be passed in argv[0] is preceded by '-' to indicate that * this is a login shell. */ if (!command) { char argv0[256]; /* Start the shell. Set initial character to '-'. */ argv0[0] = '-'; if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1) >= sizeof(argv0) - 1) { errno = EINVAL; perror(shell); exit(1); } /* Execute the shell. */ argv[0] = argv0; argv[1] = NULL; execve(shell, argv, env); /* Executing the shell failed. */ perror(shell); exit(1); } /* * Execute the command using the user's shell. This uses the -c * option to execute the command. */ argv[0] = (char *) shell0; argv[1] = "-c"; argv[2] = (char *) command; argv[3] = NULL; execve(shell, argv, env); perror(shell); exit(1); } void session_unused(int id) { debug3("%s: session id %d unused", __func__, id); if (id >= options.max_sessions || id >= sessions_nalloc) { fatal("%s: insane session id %d (max %d nalloc %d)", __func__, id, options.max_sessions, sessions_nalloc); } memset(&sessions[id], 0, sizeof(*sessions)); sessions[id].self = id; sessions[id].used = 0; sessions[id].chanid = -1; sessions[id].ptyfd = -1; sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } Session * session_new(void) { Session *s, *tmp; if (sessions_first_unused == -1) { if (sessions_nalloc >= options.max_sessions) return NULL; debug2("%s: allocate (allocated %d max %d)", __func__, sessions_nalloc, options.max_sessions); tmp = xreallocarray(sessions, sessions_nalloc + 1, sizeof(*sessions)); if (tmp == NULL) { error("%s: cannot allocate %d sessions", __func__, sessions_nalloc + 1); return NULL; } sessions = tmp; session_unused(sessions_nalloc++); } if (sessions_first_unused >= sessions_nalloc || sessions_first_unused < 0) { fatal("%s: insane first_unused %d max %d nalloc %d", __func__, sessions_first_unused, options.max_sessions, sessions_nalloc); } s = &sessions[sessions_first_unused]; if (s->used) { fatal("%s: session %d already used", __func__, sessions_first_unused); } sessions_first_unused = s->next_unused; s->used = 1; s->next_unused = -1; debug("session_new: session %d", s->self); return s; } static void session_dump(void) { int i; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; debug("dump: used %d next_unused %d session %d %p " "channel %d pid %ld", s->used, s->next_unused, s->self, s, s->chanid, (long)s->pid); } } int session_open(Authctxt *authctxt, int chanid) { Session *s = session_new(); debug("session_open: channel %d", chanid); if (s == NULL) { error("no more sessions"); return 0; } s->authctxt = authctxt; s->pw = authctxt->pw; if (s->pw == NULL || !authctxt->valid) fatal("no user for session %d", s->self); debug("session_open: session %d: link with channel %d", s->self, chanid); s->chanid = chanid; return 1; } Session * session_by_tty(char *tty) { int i; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { debug("session_by_tty: session %d tty %s", i, tty); return s; } } debug("session_by_tty: unknown tty %.100s", tty); session_dump(); return NULL; } static Session * session_by_channel(int id) { int i; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->chanid == id) { debug("session_by_channel: session %d channel %d", i, id); return s; } } debug("session_by_channel: unknown channel %d", id); session_dump(); return NULL; } static Session * session_by_x11_channel(int id) { int i, j; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->x11_chanids == NULL || !s->used) continue; for (j = 0; s->x11_chanids[j] != -1; j++) { if (s->x11_chanids[j] == id) { debug("session_by_x11_channel: session %d " "channel %d", s->self, id); return s; } } } debug("session_by_x11_channel: unknown channel %d", id); session_dump(); return NULL; } static Session * session_by_pid(pid_t pid) { int i; debug("session_by_pid: pid %ld", (long)pid); for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->pid == pid) return s; } error("session_by_pid: unknown pid %ld", (long)pid); session_dump(); return NULL; } static int session_window_change_req(Session *s) { s->col = packet_get_int(); s->row = packet_get_int(); s->xpixel = packet_get_int(); s->ypixel = packet_get_int(); packet_check_eom(); pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); return 1; } static int session_pty_req(Session *s) { u_int len; int n_bytes; if (no_pty_flag || !options.permit_tty) { debug("Allocating a pty not permitted for this authentication."); return 0; } if (s->ttyfd != -1) { packet_disconnect("Protocol error: you already have a pty."); return 0; } s->term = packet_get_string(&len); if (compat20) { s->col = packet_get_int(); s->row = packet_get_int(); } else { s->row = packet_get_int(); s->col = packet_get_int(); } s->xpixel = packet_get_int(); s->ypixel = packet_get_int(); if (strcmp(s->term, "") == 0) { free(s->term); s->term = NULL; } /* Allocate a pty and open it. */ debug("Allocating pty."); if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { free(s->term); s->term = NULL; s->ptyfd = -1; s->ttyfd = -1; error("session_pty_req: session %d alloc failed", s->self); return 0; } debug("session_pty_req: session %d alloc %s", s->self, s->tty); /* for SSH1 the tty modes length is not given */ if (!compat20) n_bytes = packet_remaining(); tty_parse_modes(s->ttyfd, &n_bytes); if (!use_privsep) pty_setowner(s->pw, s->tty); /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); packet_check_eom(); session_proctitle(s); return 1; } static int session_subsystem_req(Session *s) { struct stat st; u_int len; int success = 0; char *prog, *cmd; u_int i; s->subsys = packet_get_string(&len); packet_check_eom(); debug2("subsystem request for %.100s by user %s", s->subsys, s->pw->pw_name); for (i = 0; i < options.num_subsystems; i++) { if (strcmp(s->subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { s->is_subsystem = SUBSYSTEM_INT_SFTP; debug("subsystem: %s", prog); } else { if (stat(prog, &st) < 0) debug("subsystem: cannot stat %s: %s", prog, strerror(errno)); s->is_subsystem = SUBSYSTEM_EXT; debug("subsystem: exec() %s", cmd); } success = do_exec(s, cmd) == 0; break; } } if (!success) logit("subsystem request for %.100s by user %s failed, " "subsystem not found", s->subsys, s->pw->pw_name); return success; } static int session_x11_req(Session *s) { int success; if (s->auth_proto != NULL || s->auth_data != NULL) { error("session_x11_req: session %d: " "x11 forwarding already active", s->self); return 0; } s->single_connection = packet_get_char(); s->auth_proto = packet_get_string(NULL); s->auth_data = packet_get_string(NULL); s->screen = packet_get_int(); packet_check_eom(); if (xauth_valid_string(s->auth_proto) && xauth_valid_string(s->auth_data)) success = session_setup_x11fwd(s); else { success = 0; error("Invalid X11 forwarding data"); } if (!success) { free(s->auth_proto); free(s->auth_data); s->auth_proto = NULL; s->auth_data = NULL; } return success; } static int session_shell_req(Session *s) { packet_check_eom(); return do_exec(s, NULL) == 0; } static int session_exec_req(Session *s) { u_int len, success; char *command = packet_get_string(&len); packet_check_eom(); success = do_exec(s, command) == 0; free(command); return success; } static int session_break_req(Session *s) { packet_get_int(); /* ignored */ packet_check_eom(); if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0) return 0; return 1; } static int session_env_req(Session *s) { char *name, *val; u_int name_len, val_len, i; name = packet_get_cstring(&name_len); val = packet_get_cstring(&val_len); packet_check_eom(); /* Don't set too many environment variables */ if (s->num_env > 128) { debug2("Ignoring env request %s: too many env vars", name); goto fail; } for (i = 0; i < options.num_accept_env; i++) { if (match_pattern(name, options.accept_env[i])) { debug2("Setting env %d: %s=%s", s->num_env, name, val); s->env = xreallocarray(s->env, s->num_env + 1, sizeof(*s->env)); s->env[s->num_env].name = name; s->env[s->num_env].val = val; s->num_env++; return (1); } } debug2("Ignoring env request %s: disallowed name", name); fail: free(name); free(val); return (0); } static int session_auth_agent_req(Session *s) { static int called = 0; packet_check_eom(); if (no_agent_forwarding_flag || !options.allow_agent_forwarding) { debug("session_auth_agent_req: no_agent_forwarding_flag"); return 0; } if (called) { return 0; } else { called = 1; return auth_input_request_forwarding(s->pw); } } int session_input_channel_req(Channel *c, const char *rtype) { int success = 0; Session *s; if ((s = session_by_channel(c->self)) == NULL) { logit("session_input_channel_req: no session %d req %.100s", c->self, rtype); return 0; } debug("session_input_channel_req: session %d req %s", s->self, rtype); /* * a session is in LARVAL state until a shell, a command * or a subsystem is executed */ if (c->type == SSH_CHANNEL_LARVAL) { if (strcmp(rtype, "shell") == 0) { success = session_shell_req(s); } else if (strcmp(rtype, "exec") == 0) { success = session_exec_req(s); } else if (strcmp(rtype, "pty-req") == 0) { success = session_pty_req(s); } else if (strcmp(rtype, "x11-req") == 0) { success = session_x11_req(s); } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { success = session_auth_agent_req(s); } else if (strcmp(rtype, "subsystem") == 0) { success = session_subsystem_req(s); } else if (strcmp(rtype, "env") == 0) { success = session_env_req(s); } } if (strcmp(rtype, "window-change") == 0) { success = session_window_change_req(s); } else if (strcmp(rtype, "break") == 0) { success = session_break_req(s); } return success; } void session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, int is_tty) { if (!compat20) fatal("session_set_fds: called for proto != 2.0"); /* * now that have a child and a pipe to the child, * we can activate our channel and register the fd's */ if (s->chanid == -1) fatal("no channel for session %d", s->self); channel_set_fds(s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 1, is_tty, CHAN_SES_WINDOW_DEFAULT); } /* * Function to perform pty cleanup. Also called if we get aborted abnormally * (e.g., due to a dropped connection). */ void session_pty_cleanup2(Session *s) { if (s == NULL) { error("session_pty_cleanup: no session"); return; } if (s->ttyfd == -1) return; debug("session_pty_cleanup: session %d release %s", s->self, s->tty); /* Record that the user has logged out. */ if (s->pid != 0) record_logout(s->pid, s->tty, s->pw->pw_name); /* Release the pseudo-tty. */ if (getuid() == 0) pty_release(s->tty); /* * Close the server side of the socket pairs. We must do this after * the pty cleanup, so that another process doesn't get this pty * while we're still cleaning up. */ if (s->ptymaster != -1 && close(s->ptymaster) < 0) error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; } void session_pty_cleanup(Session *s) { PRIVSEP(session_pty_cleanup2(s)); } static char * sig2name(int sig) { #define SSH_SIG(x) if (sig == SIG ## x) return #x SSH_SIG(ABRT); SSH_SIG(ALRM); SSH_SIG(FPE); SSH_SIG(HUP); SSH_SIG(ILL); SSH_SIG(INT); SSH_SIG(KILL); SSH_SIG(PIPE); SSH_SIG(QUIT); SSH_SIG(SEGV); SSH_SIG(TERM); SSH_SIG(USR1); SSH_SIG(USR2); #undef SSH_SIG return "SIG@openssh.com"; } static void session_close_x11(int id) { Channel *c; if ((c = channel_by_id(id)) == NULL) { debug("session_close_x11: x11 channel %d missing", id); } else { /* Detach X11 listener */ debug("session_close_x11: detach x11 channel %d", id); channel_cancel_cleanup(id); if (c->ostate != CHAN_OUTPUT_CLOSED) chan_mark_dead(c); } } static void session_close_single_x11(int id, void *arg) { Session *s; u_int i; debug3("session_close_single_x11: channel %d", id); channel_cancel_cleanup(id); if ((s = session_by_x11_channel(id)) == NULL) fatal("session_close_single_x11: no x11 channel %d", id); for (i = 0; s->x11_chanids[i] != -1; i++) { debug("session_close_single_x11: session %d: " "closing channel %d", s->self, s->x11_chanids[i]); /* * The channel "id" is already closing, but make sure we * close all of its siblings. */ if (s->x11_chanids[i] != id) session_close_x11(s->x11_chanids[i]); } free(s->x11_chanids); s->x11_chanids = NULL; free(s->display); s->display = NULL; free(s->auth_proto); s->auth_proto = NULL; free(s->auth_data); s->auth_data = NULL; free(s->auth_display); s->auth_display = NULL; } static void session_exit_message(Session *s, int status) { Channel *c; if ((c = channel_lookup(s->chanid)) == NULL) fatal("session_exit_message: session %d: no channel %d", s->self, s->chanid); debug("session_exit_message: session %d channel %d pid %ld", s->self, s->chanid, (long)s->pid); if (WIFEXITED(status)) { channel_request_start(s->chanid, "exit-status", 0); packet_put_int(WEXITSTATUS(status)); packet_send(); } else if (WIFSIGNALED(status)) { channel_request_start(s->chanid, "exit-signal", 0); packet_put_cstring(sig2name(WTERMSIG(status))); #ifdef WCOREDUMP packet_put_char(WCOREDUMP(status)? 1 : 0); #else /* WCOREDUMP */ packet_put_char(0); #endif /* WCOREDUMP */ packet_put_cstring(""); packet_put_cstring(""); packet_send(); } else { /* Some weird exit cause. Just exit. */ packet_disconnect("wait returned status %04x.", status); } /* disconnect channel */ debug("session_exit_message: release channel %d", s->chanid); /* * Adjust cleanup callback attachment to send close messages when * the channel gets EOF. The session will be then be closed * by session_close_by_channel when the childs close their fds. */ channel_register_cleanup(c->self, session_close_by_channel, 1); /* * emulate a write failure with 'chan_write_failed', nobody will be * interested in data we write. * Note that we must not call 'chan_read_failed', since there could * be some more data waiting in the pipe. */ if (c->ostate != CHAN_OUTPUT_CLOSED) chan_write_failed(c); } void session_close(Session *s) { u_int i; verbose("Close session: user %s from %.200s port %d id %d", s->pw->pw_name, get_remote_ipaddr(), get_remote_port(), s->self); if (s->ttyfd != -1) session_pty_cleanup(s); free(s->term); free(s->display); free(s->x11_chanids); free(s->auth_display); free(s->auth_data); free(s->auth_proto); free(s->subsys); if (s->env != NULL) { for (i = 0; i < s->num_env; i++) { free(s->env[i].name); free(s->env[i].val); } free(s->env); } session_proctitle(s); session_unused(s->self); } void session_close_by_pid(pid_t pid, int status) { Session *s = session_by_pid(pid); if (s == NULL) { debug("session_close_by_pid: no session for pid %ld", (long)pid); return; } if (s->chanid != -1) session_exit_message(s, status); if (s->ttyfd != -1) session_pty_cleanup(s); s->pid = 0; } /* * this is called when a channel dies before * the session 'child' itself dies */ void session_close_by_channel(int id, void *arg) { Session *s = session_by_channel(id); u_int i; if (s == NULL) { debug("session_close_by_channel: no session for id %d", id); return; } debug("session_close_by_channel: channel %d child %ld", id, (long)s->pid); if (s->pid != 0) { debug("session_close_by_channel: channel %d: has child", id); /* * delay detach of session, but release pty, since * the fd's to the child are already closed */ if (s->ttyfd != -1) session_pty_cleanup(s); return; } /* detach by removing callback */ channel_cancel_cleanup(s->chanid); /* Close any X11 listeners associated with this session */ if (s->x11_chanids != NULL) { for (i = 0; s->x11_chanids[i] != -1; i++) { session_close_x11(s->x11_chanids[i]); s->x11_chanids[i] = -1; } } s->chanid = -1; session_close(s); } void session_destroy_all(void (*closefunc)(Session *)) { int i; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used) { if (closefunc != NULL) closefunc(s); else session_close(s); } } } static char * session_tty_list(void) { static char buf[1024]; int i; char *cp; buf[0] = '\0'; for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1) { if (strncmp(s->tty, "/dev/", 5) != 0) { cp = strrchr(s->tty, '/'); cp = (cp == NULL) ? s->tty : cp + 1; } else cp = s->tty + 5; if (buf[0] != '\0') strlcat(buf, ",", sizeof buf); strlcat(buf, cp, sizeof buf); } } if (buf[0] == '\0') strlcpy(buf, "notty", sizeof buf); return buf; } void session_proctitle(Session *s) { if (s->pw == NULL) error("no user for session %d", s->self); else setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); } int session_setup_x11fwd(Session *s) { struct stat st; char display[512], auth_display[512]; char hostname[NI_MAXHOST]; u_int i; if (no_x11_forwarding_flag) { packet_send_debug("X11 forwarding disabled in user configuration file."); return 0; } if (!options.x11_forwarding) { debug("X11 forwarding disabled in server configuration file."); return 0; } if (options.xauth_location == NULL || (stat(options.xauth_location, &st) == -1)) { packet_send_debug("No xauth program; cannot forward with spoofing."); return 0; } if (options.use_login) { packet_send_debug("X11 forwarding disabled; " "not compatible with UseLogin=yes."); return 0; } if (s->display != NULL) { debug("X11 display already set."); return 0; } if (x11_create_display_inet(options.x11_display_offset, options.x11_use_localhost, s->single_connection, &s->display_number, &s->x11_chanids) == -1) { debug("x11_create_display_inet failed."); return 0; } for (i = 0; s->x11_chanids[i] != -1; i++) { channel_register_cleanup(s->x11_chanids[i], session_close_single_x11, 0); } /* Set up a suitable value for the DISPLAY variable. */ if (gethostname(hostname, sizeof(hostname)) < 0) fatal("gethostname: %.100s", strerror(errno)); /* * auth_display must be used as the displayname when the * authorization entry is added with xauth(1). This will be * different than the DISPLAY string for localhost displays. */ if (options.x11_use_localhost) { snprintf(display, sizeof display, "localhost:%u.%u", s->display_number, s->screen); snprintf(auth_display, sizeof auth_display, "unix:%u.%u", s->display_number, s->screen); s->display = xstrdup(display); s->auth_display = xstrdup(auth_display); } else { #ifdef IPADDR_IN_DISPLAY struct hostent *he; struct in_addr my_addr; he = gethostbyname(hostname); if (he == NULL) { error("Can't get IP address for X11 DISPLAY."); packet_send_debug("Can't get IP address for X11 DISPLAY."); return 0; } memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr), s->display_number, s->screen); #else snprintf(display, sizeof display, "%.400s:%u.%u", hostname, s->display_number, s->screen); #endif s->display = xstrdup(display); s->auth_display = xstrdup(display); } return 1; } static void do_authenticated2(Authctxt *authctxt) { server_loop2(authctxt); } void do_cleanup(Authctxt *authctxt) { static int called = 0; debug("do_cleanup"); /* no cleanup if we're in the child for login shell */ if (is_child) return; /* avoid double cleanup */ if (called) return; called = 1; if (authctxt == NULL) return; #ifdef USE_PAM if (options.use_pam) { sshpam_cleanup(); sshpam_thread_cleanup(); } #endif if (!authctxt->authenticated) return; #ifdef KRB5 if (options.kerberos_ticket_cleanup && authctxt->krb5_ctx) krb5_cleanup_proc(authctxt); #endif #ifdef GSSAPI if (compat20 && options.gss_cleanup_creds) ssh_gssapi_cleanup_creds(); #endif /* remove agent socket */ auth_sock_cleanup_proc(authctxt->pw); /* * Cleanup ptys/utmp only if privsep is disabled, * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) session_destroy_all(session_pty_cleanup2); } openssh-7.2p2/session.h010064400017500001750000000050311267006270000133050ustar00djmdjm/* $OpenBSD: session.h,v 1.31 2013/10/14 21:20:52 djm Exp $ */ /* * Copyright (c) 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 SESSION_H #define SESSION_H #define TTYSZ 64 typedef struct Session Session; struct Session { int used; int self; int next_unused; struct passwd *pw; Authctxt *authctxt; pid_t pid; /* tty */ char *term; int ptyfd, ttyfd, ptymaster; u_int row, col, xpixel, ypixel; char tty[TTYSZ]; /* X11 */ u_int display_number; char *display; u_int screen; char *auth_display; char *auth_proto; char *auth_data; int single_connection; /* proto 2 */ int chanid; int *x11_chanids; int is_subsystem; char *subsys; u_int num_env; struct { char *name; char *val; } *env; }; void do_authenticated(Authctxt *); void do_cleanup(Authctxt *); int session_open(Authctxt *, int); void session_unused(int); int session_input_channel_req(Channel *, const char *); void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); void session_destroy_all(void (*)(Session *)); void session_pty_cleanup2(Session *); Session *session_new(void); Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *value); #endif openssh-7.2p2/sftp-client.c010064400017500001750000001416341267006270000140570ustar00djmdjm/* $OpenBSD: sftp-client.c,v 1.121 2016/02/11 02:21:34 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* XXX: memleaks */ /* XXX: signed vs unsigned */ /* XXX: remove all logging, only return status codes */ /* XXX: copy between two remote sites */ #include "includes.h" #include /* MIN MAX */ #include #ifdef HAVE_SYS_STATVFS_H #include #endif #include "openbsd-compat/sys-queue.h" #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssherr.h" #include "sshbuf.h" #include "log.h" #include "atomicio.h" #include "progressmeter.h" #include "misc.h" #include "sftp.h" #include "sftp-common.h" #include "sftp-client.h" extern volatile sig_atomic_t interrupted; extern int showprogress; /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 /* Maximum depth to descend in directory trees */ #define MAX_DIR_DEPTH 64 struct sftp_conn { int fd_in; int fd_out; u_int transfer_buflen; u_int num_requests; u_int version; u_int msg_id; #define SFTP_EXT_POSIX_RENAME 0x00000001 #define SFTP_EXT_STATVFS 0x00000002 #define SFTP_EXT_FSTATVFS 0x00000004 #define SFTP_EXT_HARDLINK 0x00000008 #define SFTP_EXT_FSYNC 0x00000010 u_int exts; u_int64_t limit_kbps; struct bwlimit bwlimit_in, bwlimit_out; }; static u_char * get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, const char *errfmt, ...) __attribute__((format(printf, 4, 5))); /* ARGSUSED */ static int sftpio(void *_bwlimit, size_t amount) { struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; bandwidth_limit(bwlimit, amount); return 0; } static void send_msg(struct sftp_conn *conn, struct sshbuf *m) { u_char mlen[4]; struct iovec iov[2]; if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH) fatal("Outbound message too long %zu", sshbuf_len(m)); /* Send length first */ put_u32(mlen, sshbuf_len(m)); iov[0].iov_base = mlen; iov[0].iov_len = sizeof(mlen); iov[1].iov_base = (u_char *)sshbuf_ptr(m); iov[1].iov_len = sshbuf_len(m); if (atomiciov6(writev, conn->fd_out, iov, 2, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) != sshbuf_len(m) + sizeof(mlen)) fatal("Couldn't send packet: %s", strerror(errno)); sshbuf_reset(m); } static void get_msg(struct sftp_conn *conn, struct sshbuf *m) { u_int msg_len; u_char *p; int r; if ((r = sshbuf_reserve(m, 4, &p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (atomicio6(read, conn->fd_in, p, 4, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { if (errno == EPIPE) fatal("Connection closed"); else fatal("Couldn't read packet: %s", strerror(errno)); } if ((r = sshbuf_get_u32(m, &msg_len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (msg_len > SFTP_MAX_MSG_LENGTH) fatal("Received message too long %u", msg_len); if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (atomicio6(read, conn->fd_in, p, msg_len, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != msg_len) { if (errno == EPIPE) fatal("Connection closed"); else fatal("Read packet: %s", strerror(errno)); } } static void send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, u_int len) { struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, code)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, s, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); sshbuf_free(msg); } static void send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, const void *s, u_int len, Attrib *a) { struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, code)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, s, len)) != 0 || (r = encode_attrib(msg, a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); sshbuf_free(msg); } static u_int get_status(struct sftp_conn *conn, u_int expected_id) { struct sshbuf *msg; u_char type; u_int id, status; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type != SSH2_FXP_STATUS) fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u", SSH2_FXP_STATUS, type); if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(msg); debug3("SSH2_FXP_STATUS %u", status); return status; } static u_char * get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, const char *errfmt, ...) { struct sshbuf *msg; u_int id, status; u_char type; u_char *handle; char errmsg[256]; va_list args; int r; va_start(args, errfmt); if (errfmt != NULL) vsnprintf(errmsg, sizeof(errmsg), errfmt, args); va_end(args); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("%s: ID mismatch (%u != %u)", errfmt == NULL ? __func__ : errmsg, id, expected_id); if (type == SSH2_FXP_STATUS) { if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (errfmt != NULL) error("%s: %s", errmsg, fx2txt(status)); sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_HANDLE) fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u", errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); if ((r = sshbuf_get_string(msg, &handle, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(msg); return handle; } static Attrib * get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) { struct sshbuf *msg; u_int id; u_char type; int r; static Attrib a; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received stat reply T:%u I:%u", type, id); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { u_int status; if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (quiet) debug("Couldn't stat remote file: %s", fx2txt(status)); else error("Couldn't stat remote file: %s", fx2txt(status)); sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_ATTRS) { fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u", SSH2_FXP_ATTRS, type); } if ((r = decode_attrib(msg, &a)) != 0) { error("%s: couldn't decode attrib: %s", __func__, ssh_err(r)); sshbuf_free(msg); return NULL; } sshbuf_free(msg); return &a; } static int get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, u_int expected_id, int quiet) { struct sshbuf *msg; u_char type; u_int id; u_int64_t flag; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received statvfs reply T:%u I:%u", type, id); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { u_int status; if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (quiet) debug("Couldn't statvfs: %s", fx2txt(status)); else error("Couldn't statvfs: %s", fx2txt(status)); sshbuf_free(msg); return -1; } else if (type != SSH2_FXP_EXTENDED_REPLY) { fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", SSH2_FXP_EXTENDED_REPLY, type); } memset(st, 0, sizeof(*st)); if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 || (r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 || (r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 || (r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 || (r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 || (r = sshbuf_get_u64(msg, &st->f_files)) != 0 || (r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 || (r = sshbuf_get_u64(msg, &st->f_favail)) != 0 || (r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 || (r = sshbuf_get_u64(msg, &flag)) != 0 || (r = sshbuf_get_u64(msg, &st->f_namemax)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; sshbuf_free(msg); return 0; } struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, u_int64_t limit_kbps) { u_char type; struct sshbuf *msg; struct sftp_conn *ret; int r; ret = xcalloc(1, sizeof(*ret)); ret->msg_id = 1; ret->fd_in = fd_in; ret->fd_out = fd_out; ret->transfer_buflen = transfer_buflen; ret->num_requests = num_requests; ret->exts = 0; ret->limit_kbps = 0; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 || (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(ret, msg); sshbuf_reset(msg); get_msg(ret, msg); /* Expecting a VERSION reply */ if ((r = sshbuf_get_u8(msg, &type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (type != SSH2_FXP_VERSION) { error("Invalid packet back from SSH2_FXP_INIT (type %u)", type); sshbuf_free(msg); free(ret); return(NULL); } if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug2("Remote version: %u", ret->version); /* Check for extensions */ while (sshbuf_len(msg) > 0) { char *name; u_char *value; size_t vlen; int known = 0; if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 || (r = sshbuf_get_string(msg, &value, &vlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp(name, "posix-rename@openssh.com") == 0 && strcmp((char *)value, "1") == 0) { ret->exts |= SFTP_EXT_POSIX_RENAME; known = 1; } else if (strcmp(name, "statvfs@openssh.com") == 0 && strcmp((char *)value, "2") == 0) { ret->exts |= SFTP_EXT_STATVFS; known = 1; } else if (strcmp(name, "fstatvfs@openssh.com") == 0 && strcmp((char *)value, "2") == 0) { ret->exts |= SFTP_EXT_FSTATVFS; known = 1; } else if (strcmp(name, "hardlink@openssh.com") == 0 && strcmp((char *)value, "1") == 0) { ret->exts |= SFTP_EXT_HARDLINK; known = 1; } else if (strcmp(name, "fsync@openssh.com") == 0 && strcmp((char *)value, "1") == 0) { ret->exts |= SFTP_EXT_FSYNC; known = 1; } if (known) { debug2("Server supports extension \"%s\" revision %s", name, value); } else { debug2("Unrecognised server extension \"%s\"", name); } free(name); free(value); } sshbuf_free(msg); /* Some filexfer v.0 servers don't support large packets */ if (ret->version == 0) ret->transfer_buflen = MIN(ret->transfer_buflen, 20480); ret->limit_kbps = limit_kbps; if (ret->limit_kbps > 0) { bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps, ret->transfer_buflen); bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps, ret->transfer_buflen); } return ret; } u_int sftp_proto_version(struct sftp_conn *conn) { return conn->version; } int do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len) { u_int id, status; struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message SSH2_FXP_CLOSE I:%u", id); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't close file: %s", fx2txt(status)); sshbuf_free(msg); return status == SSH2_FX_OK ? 0 : -1; } static int do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, SFTP_DIRENT ***dir) { struct sshbuf *msg; u_int count, id, i, expected_id, ents = 0; size_t handle_len; u_char type; char *handle; int status = SSH2_FX_FAILURE; int r; if (dir) *dir = NULL; id = conn->msg_id++; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, path)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); handle = get_handle(conn, id, &handle_len, "remote readdir(\"%s\")", path); if (handle == NULL) { sshbuf_free(msg); return -1; } if (dir) { ents = 0; *dir = xcalloc(1, sizeof(**dir)); (*dir)[0] = NULL; } for (; !interrupted;) { id = expected_id = conn->msg_id++; debug3("Sending SSH2_FXP_READDIR I:%u", id); sshbuf_reset(msg); if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); sshbuf_reset(msg); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received reply T:%u I:%u", type, id); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { u_int rstatus; if ((r = sshbuf_get_u32(msg, &rstatus)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received SSH2_FXP_STATUS %d", rstatus); if (rstatus == SSH2_FX_EOF) break; error("Couldn't read directory: %s", fx2txt(rstatus)); goto out; } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); if ((r = sshbuf_get_u32(msg, &count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count == 0) break; debug3("Received %d SSH2_FXP_NAME responses", count); for (i = 0; i < count; i++) { char *filename, *longname; Attrib a; if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((r = decode_attrib(msg, &a)) != 0) { error("%s: couldn't decode attrib: %s", __func__, ssh_err(r)); free(filename); free(longname); sshbuf_free(msg); return -1; } if (print_flag) printf("%s\n", longname); /* * Directory entries should never contain '/' * These can be used to attack recursive ops * (e.g. send '../../../../etc/passwd') */ if (strchr(filename, '/') != NULL) { error("Server sent suspect path \"%s\" " "during readdir of \"%s\"", filename, path); } else if (dir) { *dir = xreallocarray(*dir, ents + 2, sizeof(**dir)); (*dir)[ents] = xcalloc(1, sizeof(***dir)); (*dir)[ents]->filename = xstrdup(filename); (*dir)[ents]->longname = xstrdup(longname); memcpy(&(*dir)[ents]->a, &a, sizeof(a)); (*dir)[++ents] = NULL; } free(filename); free(longname); } } status = 0; out: sshbuf_free(msg); do_close(conn, handle, handle_len); free(handle); if (status != 0 && dir != NULL) { /* Don't return results on error */ free_sftp_dirents(*dir); *dir = NULL; } else if (interrupted && dir != NULL && *dir != NULL) { /* Don't return partial matches on interrupt */ free_sftp_dirents(*dir); *dir = xcalloc(1, sizeof(**dir)); **dir = NULL; } return status; } int do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) { return(do_lsreaddir(conn, path, 0, dir)); } void free_sftp_dirents(SFTP_DIRENT **s) { int i; if (s == NULL) return; for (i = 0; s[i]; i++) { free(s[i]->filename); free(s[i]->longname); free(s[i]); } free(s); } int do_rm(struct sftp_conn *conn, const char *path) { u_int status, id; debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path)); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't delete file: %s", fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) { u_int status, id; id = conn->msg_id++; send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path, strlen(path), a); status = get_status(conn, id); if (status != SSH2_FX_OK && print_flag) error("Couldn't create directory: %s", fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_rmdir(struct sftp_conn *conn, const char *path) { u_int status, id; id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_RMDIR, path, strlen(path)); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't remove directory: %s", fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } Attrib * do_stat(struct sftp_conn *conn, const char *path, int quiet) { u_int id; id = conn->msg_id++; send_string_request(conn, id, conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, path, strlen(path)); return(get_decode_stat(conn, id, quiet)); } Attrib * do_lstat(struct sftp_conn *conn, const char *path, int quiet) { u_int id; if (conn->version == 0) { if (quiet) debug("Server version does not support lstat operation"); else logit("Server version does not support lstat operation"); return(do_stat(conn, path, quiet)); } id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_LSTAT, path, strlen(path)); return(get_decode_stat(conn, id, quiet)); } #ifdef notyet Attrib * do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, int quiet) { u_int id; id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_FSTAT, handle, handle_len); return(get_decode_stat(conn, id, quiet)); } #endif int do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) { u_int status, id; id = conn->msg_id++; send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path, strlen(path), a); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't setstat on \"%s\": %s", path, fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, Attrib *a) { u_int status, id; id = conn->msg_id++; send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle, handle_len, a); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't fsetstat: %s", fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } char * do_realpath(struct sftp_conn *conn, const char *path) { struct sshbuf *msg; u_int expected_id, count, id; char *filename, *longname; Attrib a; u_char type; int r; expected_id = id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_REALPATH, path, strlen(path)); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { u_int status; if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); error("Couldn't canonicalize: %s", fx2txt(status)); sshbuf_free(msg); return NULL; } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); if ((r = sshbuf_get_u32(msg, &count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count != 1) fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || (r = decode_attrib(msg, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, (unsigned long)a.size); free(longname); sshbuf_free(msg); return(filename); } int do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, int force_legacy) { struct sshbuf *msg; u_int status, id; int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Send rename request */ id = conn->msg_id++; if (use_ext) { if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } else { if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 || (r = sshbuf_put_cstring(msg, newpath)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message %s \"%s\" -> \"%s\"", use_ext ? "posix-rename@openssh.com" : "SSH2_FXP_RENAME", oldpath, newpath); sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) { struct sshbuf *msg; u_int status, id; int r; if ((conn->exts & SFTP_EXT_HARDLINK) == 0) { error("Server does not support hardlink@openssh.com extension"); return -1; } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Send link request */ id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, oldpath)) != 0 || (r = sshbuf_put_cstring(msg, newpath)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", oldpath, newpath); sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't link file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) { struct sshbuf *msg; u_int status, id; int r; if (conn->version < 3) { error("This server does not support the symlink operation"); return(SSH2_FX_OP_UNSUPPORTED); } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Send symlink request */ id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, oldpath)) != 0 || (r = sshbuf_put_cstring(msg, newpath)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, newpath); sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); return status == SSH2_FX_OK ? 0 : -1; } int do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len) { struct sshbuf *msg; u_int status, id; int r; /* Silently return if the extension is not supported */ if ((conn->exts & SFTP_EXT_FSYNC) == 0) return -1; /* Send fsync request */ if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message fsync@openssh.com I:%u", id); sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't sync file: %s", fx2txt(status)); return status; } #ifdef notyet char * do_readlink(struct sftp_conn *conn, const char *path) { struct sshbuf *msg; u_int expected_id, count, id; char *filename, *longname; Attrib a; u_char type; int r; expected_id = id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { u_int status; if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); error("Couldn't readlink: %s", fx2txt(status)); sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); if ((r = sshbuf_get_u32(msg, &count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count != 1) fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || (r = decode_attrib(msg, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("SSH_FXP_READLINK %s -> %s", path, filename); free(longname); sshbuf_free(msg); return filename; } #endif int do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, int quiet) { struct sshbuf *msg; u_int id; int r; if ((conn->exts & SFTP_EXT_STATVFS) == 0) { error("Server does not support statvfs@openssh.com extension"); return -1; } id = conn->msg_id++; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); sshbuf_reset(msg); if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, path)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); sshbuf_free(msg); return get_decode_statvfs(conn, st, id, quiet); } #ifdef notyet int do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len, struct sftp_statvfs *st, int quiet) { struct sshbuf *msg; u_int id; if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { error("Server does not support fstatvfs@openssh.com extension"); return -1; } id = conn->msg_id++; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); sshbuf_reset(msg); if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); sshbuf_free(msg); return get_decode_statvfs(conn, st, id, quiet); } #endif static void send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, u_int len, const u_char *handle, u_int handle_len) { struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); sshbuf_reset(msg); if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || (r = sshbuf_put_u64(msg, offset)) != 0 || (r = sshbuf_put_u32(msg, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); sshbuf_free(msg); } int do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) { Attrib junk; struct sshbuf *msg; u_char *handle; int local_fd = -1, write_error; int read_error, write_errno, reordered = 0, r; u_int64_t offset = 0, size, highwater; u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK; off_t progress_counter; size_t handle_len; struct stat st; struct request { u_int id; size_t len; u_int64_t offset; TAILQ_ENTRY(request) tq; }; TAILQ_HEAD(reqhead, request) requests; struct request *req; u_char type; TAILQ_INIT(&requests); if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL) return -1; /* Do not preserve set[ug]id here, as we do not preserve ownership */ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) mode = a->perm & 0777; else mode = 0666; if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && (!S_ISREG(a->perm))) { error("Cannot download non-regular file: %s", remote_path); return(-1); } if (a->flags & SSH2_FILEXFER_ATTR_SIZE) size = a->size; else size = 0; buflen = conn->transfer_buflen; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); attrib_clear(&junk); /* Send empty attributes */ /* Send open request */ id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, remote_path)) != 0 || (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || (r = encode_attrib(msg, &junk)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { sshbuf_free(msg); return(-1); } local_fd = open(local_path, O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR); if (local_fd == -1) { error("Couldn't open local file \"%s\" for writing: %s", local_path, strerror(errno)); goto fail; } offset = highwater = 0; if (resume_flag) { if (fstat(local_fd, &st) == -1) { error("Unable to stat local file \"%s\": %s", local_path, strerror(errno)); goto fail; } if (st.st_size < 0) { error("\"%s\" has negative size", local_path); goto fail; } if ((u_int64_t)st.st_size > size) { error("Unable to resume download of \"%s\": " "local file is larger than remote", local_path); fail: do_close(conn, handle, handle_len); sshbuf_free(msg); free(handle); if (local_fd != -1) close(local_fd); return -1; } offset = highwater = st.st_size; } /* Read from remote and write to local */ write_error = read_error = write_errno = num_req = 0; max_req = 1; progress_counter = offset; if (showprogress && size != 0) start_progress_meter(remote_path, size, &progress_counter); while (num_req > 0 || max_req > 0) { u_char *data; size_t len; /* * Simulate EOF on interrupt: stop sending new requests and * allow outstanding requests to drain gracefully */ if (interrupted) { if (num_req == 0) /* If we haven't started yet... */ break; max_req = 0; } /* Send some more requests */ while (num_req < max_req) { debug3("Request range %llu -> %llu (%d/%d)", (unsigned long long)offset, (unsigned long long)offset + buflen - 1, num_req, max_req); req = xcalloc(1, sizeof(*req)); req->id = conn->msg_id++; req->len = buflen; req->offset = offset; offset += buflen; num_req++; TAILQ_INSERT_TAIL(&requests, req, tq); send_read_request(conn, req->id, req->offset, req->len, handle, handle_len); } sshbuf_reset(msg); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received reply T:%u I:%u R:%d", type, id, max_req); /* Find the request in our queue */ for (req = TAILQ_FIRST(&requests); req != NULL && req->id != id; req = TAILQ_NEXT(req, tq)) ; if (req == NULL) fatal("Unexpected reply %u", id); switch (type) { case SSH2_FXP_STATUS: if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (status != SSH2_FX_EOF) read_error = 1; max_req = 0; TAILQ_REMOVE(&requests, req, tq); free(req); num_req--; break; case SSH2_FXP_DATA: if ((r = sshbuf_get_string(msg, &data, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received data %llu -> %llu", (unsigned long long)req->offset, (unsigned long long)req->offset + len - 1); if (len > req->len) fatal("Received more data than asked for " "%zu > %zu", len, req->len); if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || atomicio(vwrite, local_fd, data, len) != len) && !write_error) { write_errno = errno; write_error = 1; max_req = 0; } else if (!reordered && req->offset <= highwater) highwater = req->offset + len; else if (!reordered && req->offset > highwater) reordered = 1; progress_counter += len; free(data); if (len == req->len) { TAILQ_REMOVE(&requests, req, tq); free(req); num_req--; } else { /* Resend the request for the missing data */ debug3("Short data block, re-requesting " "%llu -> %llu (%2d)", (unsigned long long)req->offset + len, (unsigned long long)req->offset + req->len - 1, num_req); req->id = conn->msg_id++; req->len -= len; req->offset += len; send_read_request(conn, req->id, req->offset, req->len, handle, handle_len); /* Reduce the request size */ if (len < buflen) buflen = MAX(MIN_READ_SIZE, len); } if (max_req > 0) { /* max_req = 0 iff EOF received */ if (size > 0 && offset > size) { /* Only one request at a time * after the expected EOF */ debug3("Finish at %llu (%2d)", (unsigned long long)offset, num_req); max_req = 1; } else if (max_req <= conn->num_requests) { ++max_req; } } break; default: fatal("Expected SSH2_FXP_DATA(%u) packet, got %u", SSH2_FXP_DATA, type); } } if (showprogress && size) stop_progress_meter(); /* Sanity check */ if (TAILQ_FIRST(&requests) != NULL) fatal("Transfer complete, but requests still in queue"); /* Truncate at highest contiguous point to avoid holes on interrupt */ if (read_error || write_error || interrupted) { if (reordered && resume_flag) { error("Unable to resume download of \"%s\": " "server reordered requests", local_path); } debug("truncating at %llu", (unsigned long long)highwater); if (ftruncate(local_fd, highwater) == -1) error("ftruncate \"%s\": %s", local_path, strerror(errno)); } if (read_error) { error("Couldn't read from remote file \"%s\" : %s", remote_path, fx2txt(status)); status = -1; do_close(conn, handle, handle_len); } else if (write_error) { error("Couldn't write to \"%s\": %s", local_path, strerror(write_errno)); status = SSH2_FX_FAILURE; do_close(conn, handle, handle_len); } else { if (do_close(conn, handle, handle_len) != 0 || interrupted) status = SSH2_FX_FAILURE; else status = SSH2_FX_OK; /* Override umask and utimes if asked */ #ifdef HAVE_FCHMOD if (preserve_flag && fchmod(local_fd, mode) == -1) #else if (preserve_flag && chmod(local_path, mode) == -1) #endif /* HAVE_FCHMOD */ error("Couldn't set mode on \"%s\": %s", local_path, strerror(errno)); if (preserve_flag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { struct timeval tv[2]; tv[0].tv_sec = a->atime; tv[1].tv_sec = a->mtime; tv[0].tv_usec = tv[1].tv_usec = 0; if (utimes(local_path, tv) == -1) error("Can't set times on \"%s\": %s", local_path, strerror(errno)); } if (fsync_flag) { debug("syncing \"%s\"", local_path); if (fsync(local_fd) == -1) error("Couldn't sync file \"%s\": %s", local_path, strerror(errno)); } } close(local_fd); sshbuf_free(msg); free(handle); return(status); } static int download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, int fsync_flag) { int i, ret = 0; SFTP_DIRENT **dir_entries; char *filename, *new_src, *new_dst; mode_t mode = 0777; if (depth >= MAX_DIR_DEPTH) { error("Maximum directory depth exceeded: %d levels", depth); return -1; } if (dirattrib == NULL && (dirattrib = do_stat(conn, src, 1)) == NULL) { error("Unable to stat remote directory \"%s\"", src); return -1; } if (!S_ISDIR(dirattrib->perm)) { error("\"%s\" is not a directory", src); return -1; } if (print_flag) printf("Retrieving %s\n", src); if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) mode = dirattrib->perm & 01777; else { debug("Server did not send permissions for " "directory \"%s\"", dst); } if (mkdir(dst, mode) == -1 && errno != EEXIST) { error("mkdir %s: %s", dst, strerror(errno)); return -1; } if (do_readdir(conn, src, &dir_entries) == -1) { error("%s: Failed to get directory contents", src); return -1; } for (i = 0; dir_entries[i] != NULL && !interrupted; i++) { filename = dir_entries[i]->filename; new_dst = path_append(dst, filename); new_src = path_append(src, filename); if (S_ISDIR(dir_entries[i]->a.perm)) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; if (download_dir_internal(conn, new_src, new_dst, depth + 1, &(dir_entries[i]->a), preserve_flag, print_flag, resume_flag, fsync_flag) == -1) ret = -1; } else if (S_ISREG(dir_entries[i]->a.perm) ) { if (do_download(conn, new_src, new_dst, &(dir_entries[i]->a), preserve_flag, resume_flag, fsync_flag) == -1) { error("Download of file %s to %s failed", new_src, new_dst); ret = -1; } } else logit("%s: not a regular file\n", new_src); free(new_dst); free(new_src); } if (preserve_flag) { if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { struct timeval tv[2]; tv[0].tv_sec = dirattrib->atime; tv[1].tv_sec = dirattrib->mtime; tv[0].tv_usec = tv[1].tv_usec = 0; if (utimes(dst, tv) == -1) error("Can't set times on \"%s\": %s", dst, strerror(errno)); } else debug("Server did not send times for directory " "\"%s\"", dst); } free_sftp_dirents(dir_entries); return ret; } int download_dir(struct sftp_conn *conn, const char *src, const char *dst, Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, int fsync_flag) { char *src_canon; int ret; if ((src_canon = do_realpath(conn, src)) == NULL) { error("Unable to canonicalize path \"%s\"", src); return -1; } ret = download_dir_internal(conn, src_canon, dst, 0, dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag); free(src_canon); return ret; } int do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, int preserve_flag, int resume, int fsync_flag) { int r, local_fd; u_int status = SSH2_FX_OK; u_int id; u_char type; off_t offset, progress_counter; u_char *handle, *data; struct sshbuf *msg; struct stat sb; Attrib a, *c = NULL; u_int32_t startid; u_int32_t ackid; struct outstanding_ack { u_int id; u_int len; off_t offset; TAILQ_ENTRY(outstanding_ack) tq; }; TAILQ_HEAD(ackhead, outstanding_ack) acks; struct outstanding_ack *ack = NULL; size_t handle_len; TAILQ_INIT(&acks); if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { error("Couldn't open local file \"%s\" for reading: %s", local_path, strerror(errno)); return(-1); } if (fstat(local_fd, &sb) == -1) { error("Couldn't fstat local file \"%s\": %s", local_path, strerror(errno)); close(local_fd); return(-1); } if (!S_ISREG(sb.st_mode)) { error("%s is not a regular file", local_path); close(local_fd); return(-1); } stat_to_attrib(&sb, &a); a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; a.perm &= 0777; if (!preserve_flag) a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; if (resume) { /* Get remote file size if it exists */ if ((c = do_stat(conn, remote_path, 0)) == NULL) { close(local_fd); return -1; } if ((off_t)c->size >= sb.st_size) { error("destination file bigger or same size as " "source file"); close(local_fd); return -1; } if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) { close(local_fd); return -1; } } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Send open request */ id = conn->msg_id++; if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_cstring(msg, remote_path)) != 0 || (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 || (r = encode_attrib(msg, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); sshbuf_reset(msg); handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { close(local_fd); sshbuf_free(msg); return -1; } startid = ackid = id + 1; data = xmalloc(conn->transfer_buflen); /* Read from local and write to remote */ offset = progress_counter = (resume ? c->size : 0); if (showprogress) start_progress_meter(local_path, sb.st_size, &progress_counter); for (;;) { int len; /* * Can't use atomicio here because it returns 0 on EOF, * thus losing the last block of the file. * Simulate an EOF on interrupt, allowing ACKs from the * server to drain. */ if (interrupted || status != SSH2_FX_OK) len = 0; else do len = read(local_fd, data, conn->transfer_buflen); while ((len == -1) && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); if (len == -1) fatal("Couldn't read from \"%s\": %s", local_path, strerror(errno)); if (len != 0) { ack = xcalloc(1, sizeof(*ack)); ack->id = ++id; ack->offset = offset; ack->len = len; TAILQ_INSERT_TAIL(&acks, ack, tq); sshbuf_reset(msg); if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 || (r = sshbuf_put_u32(msg, ack->id)) != 0 || (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || (r = sshbuf_put_u64(msg, offset)) != 0 || (r = sshbuf_put_string(msg, data, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(conn, msg); debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", id, (unsigned long long)offset, len); } else if (TAILQ_FIRST(&acks) == NULL) break; if (ack == NULL) fatal("Unexpected ACK %u", id); if (id == startid || len == 0 || id - ackid >= conn->num_requests) { u_int rid; sshbuf_reset(msg); get_msg(conn, msg); if ((r = sshbuf_get_u8(msg, &type)) != 0 || (r = sshbuf_get_u32(msg, &rid)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (type != SSH2_FXP_STATUS) fatal("Expected SSH2_FXP_STATUS(%d) packet, " "got %d", SSH2_FXP_STATUS, type); if ((r = sshbuf_get_u32(msg, &status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("SSH2_FXP_STATUS %u", status); /* Find the request in our queue */ for (ack = TAILQ_FIRST(&acks); ack != NULL && ack->id != rid; ack = TAILQ_NEXT(ack, tq)) ; if (ack == NULL) fatal("Can't find request for ID %u", rid); TAILQ_REMOVE(&acks, ack, tq); debug3("In write loop, ack for %u %u bytes at %lld", ack->id, ack->len, (long long)ack->offset); ++ackid; progress_counter += ack->len; free(ack); } offset += len; if (offset < 0) fatal("%s: offset < 0", __func__); } sshbuf_free(msg); if (showprogress) stop_progress_meter(); free(data); if (status != SSH2_FX_OK) { error("Couldn't write to remote file \"%s\": %s", remote_path, fx2txt(status)); status = SSH2_FX_FAILURE; } if (close(local_fd) == -1) { error("Couldn't close local file \"%s\": %s", local_path, strerror(errno)); status = SSH2_FX_FAILURE; } /* Override umask and utimes if asked */ if (preserve_flag) do_fsetstat(conn, handle, handle_len, &a); if (fsync_flag) (void)do_fsync(conn, handle, handle_len); if (do_close(conn, handle, handle_len) != 0) status = SSH2_FX_FAILURE; free(handle); return status == SSH2_FX_OK ? 0 : -1; } static int upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, int preserve_flag, int print_flag, int resume, int fsync_flag) { int ret = 0; DIR *dirp; struct dirent *dp; char *filename, *new_src, *new_dst; struct stat sb; Attrib a, *dirattrib; if (depth >= MAX_DIR_DEPTH) { error("Maximum directory depth exceeded: %d levels", depth); return -1; } if (stat(src, &sb) == -1) { error("Couldn't stat directory \"%s\": %s", src, strerror(errno)); return -1; } if (!S_ISDIR(sb.st_mode)) { error("\"%s\" is not a directory", src); return -1; } if (print_flag) printf("Entering %s\n", src); attrib_clear(&a); stat_to_attrib(&sb, &a); a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID; a.perm &= 01777; if (!preserve_flag) a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; /* * sftp lacks a portable status value to match errno EEXIST, * so if we get a failure back then we must check whether * the path already existed and is a directory. */ if (do_mkdir(conn, dst, &a, 0) != 0) { if ((dirattrib = do_stat(conn, dst, 0)) == NULL) return -1; if (!S_ISDIR(dirattrib->perm)) { error("\"%s\" exists but is not a directory", dst); return -1; } } if ((dirp = opendir(src)) == NULL) { error("Failed to open dir \"%s\": %s", src, strerror(errno)); return -1; } while (((dp = readdir(dirp)) != NULL) && !interrupted) { if (dp->d_ino == 0) continue; filename = dp->d_name; new_dst = path_append(dst, filename); new_src = path_append(src, filename); if (lstat(new_src, &sb) == -1) { logit("%s: lstat failed: %s", filename, strerror(errno)); ret = -1; } else if (S_ISDIR(sb.st_mode)) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; if (upload_dir_internal(conn, new_src, new_dst, depth + 1, preserve_flag, print_flag, resume, fsync_flag) == -1) ret = -1; } else if (S_ISREG(sb.st_mode)) { if (do_upload(conn, new_src, new_dst, preserve_flag, resume, fsync_flag) == -1) { error("Uploading of file %s to %s failed!", new_src, new_dst); ret = -1; } } else logit("%s: not a regular file\n", filename); free(new_dst); free(new_src); } do_setstat(conn, dst, &a); (void) closedir(dirp); return ret; } int upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, int print_flag, int resume, int fsync_flag) { char *dst_canon; int ret; if ((dst_canon = do_realpath(conn, dst)) == NULL) { error("Unable to canonicalize path \"%s\"", dst); return -1; } ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, print_flag, resume, fsync_flag); free(dst_canon); return ret; } char * path_append(const char *p1, const char *p2) { char *ret; size_t len = strlen(p1) + strlen(p2) + 2; ret = xmalloc(len); strlcpy(ret, p1, len); if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') strlcat(ret, "/", len); strlcat(ret, p2, len); return(ret); } openssh-7.2p2/sftp-client.h010064400017500001750000000104471267006270000140610ustar00djmdjm/* $OpenBSD: sftp-client.h,v 1.27 2015/05/08 06:45:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ /* Client side of SSH2 filexfer protocol */ #ifndef _SFTP_CLIENT_H #define _SFTP_CLIENT_H #ifdef USE_SYSTEM_GLOB # include #else # include "openbsd-compat/glob.h" #endif typedef struct SFTP_DIRENT SFTP_DIRENT; struct SFTP_DIRENT { char *filename; char *longname; Attrib a; }; /* * Used for statvfs responses on the wire from the server, because the * server's native format may be larger than the client's. */ struct sftp_statvfs { u_int64_t f_bsize; u_int64_t f_frsize; u_int64_t f_blocks; u_int64_t f_bfree; u_int64_t f_bavail; u_int64_t f_files; u_int64_t f_ffree; u_int64_t f_favail; u_int64_t f_fsid; u_int64_t f_flag; u_int64_t f_namemax; }; /* * Initialise a SSH filexfer connection. Returns NULL on error or * a pointer to a initialized sftp_conn struct on success. */ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); u_int sftp_proto_version(struct sftp_conn *); /* Close file referred to by 'handle' */ int do_close(struct sftp_conn *, const u_char *, u_int); /* Read contents of 'path' to NULL-terminated array 'dir' */ int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ void free_sftp_dirents(SFTP_DIRENT **); /* Delete file 'path' */ int do_rm(struct sftp_conn *, const char *); /* Create directory 'path' */ int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); /* Remove directory 'path' */ int do_rmdir(struct sftp_conn *, const char *); /* Get file attributes of 'path' (follows symlinks) */ Attrib *do_stat(struct sftp_conn *, const char *, int); /* Get file attributes of 'path' (does not follow symlinks) */ Attrib *do_lstat(struct sftp_conn *, const char *, int); /* Set file attributes of 'path' */ int do_setstat(struct sftp_conn *, const char *, Attrib *); /* Set file attributes of open file 'handle' */ int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *); /* Canonicalise 'path' - caller must free result */ char *do_realpath(struct sftp_conn *, const char *); /* Get statistics for filesystem hosting file at "path" */ int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); /* Rename 'oldpath' to 'newpath' */ int do_rename(struct sftp_conn *, const char *, const char *, int force_legacy); /* Link 'oldpath' to 'newpath' */ int do_hardlink(struct sftp_conn *, const char *, const char *); /* Rename 'oldpath' to 'newpath' */ int do_symlink(struct sftp_conn *, const char *, const char *); /* Call fsync() on open file 'handle' */ int do_fsync(struct sftp_conn *conn, u_char *, u_int); /* * Download 'remote_path' to 'local_path'. Preserve permissions and times * if 'pflag' is set */ int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int); /* * Recursively download 'remote_directory' to 'local_directory'. Preserve * times if 'pflag' is set */ int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int, int); /* * Upload 'local_path' to 'remote_path'. Preserve permissions and times * if 'pflag' is set */ int do_upload(struct sftp_conn *, const char *, const char *, int, int, int); /* * Recursively upload 'local_directory' to 'remote_directory'. Preserve * times if 'pflag' is set */ int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, int); /* Concatenate paths, taking care of slashes. Caller must free result. */ char *path_append(const char *, const char *); #endif openssh-7.2p2/sftp-common.c010064400017500001750000000154431267006270000140670ustar00djmdjm/* $OpenBSD: sftp-common.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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 /* MAX */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_UTIL_H #include #endif #include "xmalloc.h" #include "ssherr.h" #include "sshbuf.h" #include "log.h" #include "sftp.h" #include "sftp-common.h" /* Clear contents of attributes structure */ void attrib_clear(Attrib *a) { a->flags = 0; a->size = 0; a->uid = 0; a->gid = 0; a->perm = 0; a->atime = 0; a->mtime = 0; } /* Convert from struct stat to filexfer attribs */ void stat_to_attrib(const struct stat *st, Attrib *a) { attrib_clear(a); a->flags = 0; a->flags |= SSH2_FILEXFER_ATTR_SIZE; a->size = st->st_size; a->flags |= SSH2_FILEXFER_ATTR_UIDGID; a->uid = st->st_uid; a->gid = st->st_gid; a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a->perm = st->st_mode; a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; a->atime = st->st_atime; a->mtime = st->st_mtime; } /* Convert from filexfer attribs to struct stat */ void attrib_to_stat(const Attrib *a, struct stat *st) { memset(st, 0, sizeof(*st)); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) st->st_size = a->size; if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { st->st_uid = a->uid; st->st_gid = a->gid; } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) st->st_mode = a->perm; if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { st->st_atime = a->atime; st->st_mtime = a->mtime; } } /* Decode attributes in buffer */ int decode_attrib(struct sshbuf *b, Attrib *a) { int r; attrib_clear(a); if ((r = sshbuf_get_u32(b, &a->flags)) != 0) return r; if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { if ((r = sshbuf_get_u64(b, &a->size)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { if ((r = sshbuf_get_u32(b, &a->uid)) != 0 || (r = sshbuf_get_u32(b, &a->gid)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { if ((r = sshbuf_get_u32(b, &a->perm)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { if ((r = sshbuf_get_u32(b, &a->atime)) != 0 || (r = sshbuf_get_u32(b, &a->mtime)) != 0) return r; } /* vendor-specific extensions */ if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) { char *type; u_char *data; size_t dlen; u_int i, count; if ((r = sshbuf_get_u32(b, &count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; i < count; i++) { if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 || (r = sshbuf_get_string(b, &data, &dlen)) != 0) return r; debug3("Got file attribute \"%.100s\" len %zu", type, dlen); free(type); free(data); } } return 0; } /* Encode attributes to buffer */ int encode_attrib(struct sshbuf *b, const Attrib *a) { int r; if ((r = sshbuf_put_u32(b, a->flags)) != 0) return r; if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { if ((r = sshbuf_put_u64(b, a->size)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { if ((r = sshbuf_put_u32(b, a->uid)) != 0 || (r = sshbuf_put_u32(b, a->gid)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { if ((r = sshbuf_put_u32(b, a->perm)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { if ((r = sshbuf_put_u32(b, a->atime)) != 0 || (r = sshbuf_put_u32(b, a->mtime)) != 0) return r; } return 0; } /* Convert from SSH2_FX_ status to text error message */ const char * fx2txt(int status) { switch (status) { case SSH2_FX_OK: return("No error"); case SSH2_FX_EOF: return("End of file"); case SSH2_FX_NO_SUCH_FILE: return("No such file or directory"); case SSH2_FX_PERMISSION_DENIED: return("Permission denied"); case SSH2_FX_FAILURE: return("Failure"); case SSH2_FX_BAD_MESSAGE: return("Bad message"); case SSH2_FX_NO_CONNECTION: return("No connection"); case SSH2_FX_CONNECTION_LOST: return("Connection lost"); case SSH2_FX_OP_UNSUPPORTED: return("Operation unsupported"); default: return("Unknown status"); } /* NOTREACHED */ } /* * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh */ char * ls_file(const char *name, const struct stat *st, int remote, int si_units) { int ulen, glen, sz = 0; struct tm *ltime = localtime(&st->st_mtime); char *user, *group; char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; char sbuf[FMT_SCALED_STRSIZE]; time_t now; strmode(st->st_mode, mode); if (!remote) { user = user_from_uid(st->st_uid, 0); } else { snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); user = ubuf; } if (!remote) { group = group_from_gid(st->st_gid, 0); } else { snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); group = gbuf; } if (ltime != NULL) { now = time(NULL); if (now - (365*24*60*60)/2 < st->st_mtime && now >= st->st_mtime) sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); else sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); } if (sz == 0) tbuf[0] = '\0'; ulen = MAX(strlen(user), 8); glen = MAX(strlen(group), 8); if (si_units) { fmt_scaled((long long)st->st_size, sbuf); snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode, (u_int)st->st_nlink, ulen, user, glen, group, sbuf, tbuf, name); } else { snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, (u_int)st->st_nlink, ulen, user, glen, group, (unsigned long long)st->st_size, tbuf, name); } return xstrdup(buf); } openssh-7.2p2/sftp-common.h010064400017500001750000000040301267006270000140620ustar00djmdjm/* $OpenBSD: sftp-common.h,v 1.12 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * 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. */ /* Maximum packet that we are willing to send/accept */ #define SFTP_MAX_MSG_LENGTH (256 * 1024) struct sshbuf; typedef struct Attrib Attrib; /* File attributes */ struct Attrib { u_int32_t flags; u_int64_t size; u_int32_t uid; u_int32_t gid; u_int32_t perm; u_int32_t atime; u_int32_t mtime; }; void attrib_clear(Attrib *); void stat_to_attrib(const struct stat *, Attrib *); void attrib_to_stat(const Attrib *, struct stat *); int decode_attrib(struct sshbuf *, Attrib *); int encode_attrib(struct sshbuf *, const Attrib *); char *ls_file(const char *, const struct stat *, int, int); const char *fx2txt(int); openssh-7.2p2/sftp-glob.c010064400017500001750000000066121267006270000135200ustar00djmdjm/* $OpenBSD: sftp-glob.c,v 1.27 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #ifdef HAVE_SYS_STAT_H # include #endif #include #include #include #include #include "xmalloc.h" #include "sftp.h" #include "sftp-common.h" #include "sftp-client.h" int remote_glob(struct sftp_conn *, const char *, int, int (*)(const char *, int), glob_t *); struct SFTP_OPENDIR { SFTP_DIRENT **dir; int offset; }; static struct { struct sftp_conn *conn; } cur; static void * fudge_opendir(const char *path) { struct SFTP_OPENDIR *r; r = xcalloc(1, sizeof(*r)); if (do_readdir(cur.conn, (char *)path, &r->dir)) { free(r); return(NULL); } r->offset = 0; return((void *)r); } static struct dirent * fudge_readdir(struct SFTP_OPENDIR *od) { /* Solaris needs sizeof(dirent) + path length (see below) */ static char buf[sizeof(struct dirent) + MAXPATHLEN]; struct dirent *ret = (struct dirent *)buf; #ifdef __GNU_LIBRARY__ static int inum = 1; #endif /* __GNU_LIBRARY__ */ if (od->dir[od->offset] == NULL) return(NULL); memset(buf, 0, sizeof(buf)); /* * Solaris defines dirent->d_name as a one byte array and expects * you to hack around it. */ #ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); #else strlcpy(ret->d_name, od->dir[od->offset++]->filename, sizeof(ret->d_name)); #endif #ifdef __GNU_LIBRARY__ /* * Idiot glibc uses extensions to struct dirent for readdir with * ALTDIRFUNCs. Not that this is documented anywhere but the * source... Fake an inode number to appease it. */ ret->d_ino = inum++; if (!inum) inum = 1; #endif /* __GNU_LIBRARY__ */ return(ret); } static void fudge_closedir(struct SFTP_OPENDIR *od) { free_sftp_dirents(od->dir); free(od); } static int fudge_lstat(const char *path, struct stat *st) { Attrib *a; if (!(a = do_lstat(cur.conn, (char *)path, 1))) return(-1); attrib_to_stat(a, st); return(0); } static int fudge_stat(const char *path, struct stat *st) { Attrib *a; if (!(a = do_stat(cur.conn, (char *)path, 1))) return(-1); attrib_to_stat(a, st); return(0); } int remote_glob(struct sftp_conn *conn, const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) { pglob->gl_opendir = fudge_opendir; pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; pglob->gl_closedir = (void (*)(void *))fudge_closedir; pglob->gl_lstat = fudge_lstat; pglob->gl_stat = fudge_stat; memset(&cur, 0, sizeof(cur)); cur.conn = conn; return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); } openssh-7.2p2/sftp-server-main.c010064400017500001750000000027651267006270000150320ustar00djmdjm/* $OpenBSD: sftp-server-main.c,v 1.5 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2008 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #include #include #include #include #include "log.h" #include "sftp.h" #include "misc.h" #include "xmalloc.h" void cleanup_exit(int i) { sftp_server_cleanup_exit(i); } int main(int argc, char **argv) { struct passwd *user_pw; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); if ((user_pw = getpwuid(getuid())) == NULL) { fprintf(stderr, "No user found for uid %lu\n", (u_long)getuid()); return 1; } return (sftp_server_main(argc, argv, user_pw)); } openssh-7.2p2/sftp-server.8010064400017500001750000000117551267006270000140340ustar00djmdjm.\" $OpenBSD: sftp-server.8,v 1.27 2014/12/11 04:16:14 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. .\" .Dd $Mdocdate: December 11 2014 $ .Dt SFTP-SERVER 8 .Os .Sh NAME .Nm sftp-server .Nd SFTP server subsystem .Sh SYNOPSIS .Nm sftp-server .Bk -words .Op Fl ehR .Op Fl d Ar start_directory .Op Fl f Ar log_facility .Op Fl l Ar log_level .Op Fl P Ar blacklisted_requests .Op Fl p Ar whitelisted_requests .Op Fl u Ar umask .Ek .Nm .Fl Q Ar protocol_feature .Sh DESCRIPTION .Nm is a program that speaks the server side of SFTP protocol to stdout and expects client requests from stdin. .Nm is not intended to be called directly, but from .Xr sshd 8 using the .Cm Subsystem option. .Pp Command-line flags to .Nm should be specified in the .Cm Subsystem declaration. See .Xr sshd_config 5 for more information. .Pp Valid options are: .Bl -tag -width Ds .It Fl d Ar start_directory specifies an alternate starting directory for users. The pathname may contain the following tokens that are expanded at runtime: %% is replaced by a literal '%', %d is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. The default is to use the user's home directory. This option is useful in conjunction with the .Xr sshd_config 5 .Cm ChrootDirectory option. .It Fl e Causes .Nm to print logging information to stderr instead of syslog for debugging. .It Fl f Ar log_facility Specifies the facility code that is used when logging messages from .Nm . The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Fl h Displays .Nm usage information. .It Fl l Ar log_level Specifies which messages will be logged by .Nm . The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions that .Nm performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. .It Fl P Ar blacklisted_requests Specify a comma-separated list of SFTP protocol requests that are banned by the server. .Nm will reply to any blacklisted request with a failure. The .Fl Q flag can be used to determine the supported request types. If both a blacklist and a whitelist are specified, then the blacklist is applied before the whitelist. .It Fl p Ar whitelisted_requests Specify a comma-separated list of SFTP protocol requests that are permitted by the server. All request types that are not on the whitelist will be logged and replied to with a failure message. .Pp Care must be taken when using this feature to ensure that requests made implicitly by SFTP clients are permitted. .It Fl Q Ar protocol_feature Query protocol features supported by .Nm . At present the only feature that may be queried is .Dq requests , which may be used for black or whitelisting (flags .Fl P and .Fl p respectively). .It Fl R Places this instance of .Nm into a read-only mode. Attempts to open files for writing, as well as other operations that change the state of the filesystem, will be denied. .It Fl u Ar umask Sets an explicit .Xr umask 2 to be applied to newly-created files and directories, instead of the user's default mask. .El .Pp On some systems, .Nm must be able to access .Pa /dev/log for logging to work, and use of .Nm in a chroot configuration therefore requires that .Xr syslogd 8 establish a logging socket inside the chroot directory. .Sh SEE ALSO .Xr sftp 1 , .Xr ssh 1 , .Xr sshd_config 5 , .Xr sshd 8 .Rs .%A T. Ylonen .%A S. Lehtinen .%T "SSH File Transfer Protocol" .%N draft-ietf-secsh-filexfer-02.txt .%D October 2001 .%O work in progress material .Re .Sh HISTORY .Nm first appeared in .Ox 2.8 . .Sh AUTHORS .An Markus Friedl Aq Mt markus@openbsd.org openssh-7.2p2/sftp-server.c010064400017500001750000001247631267006270000141130ustar00djmdjm/* $OpenBSD: sftp-server.c,v 1.109 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include /* MIN */ #include #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif #ifdef HAVE_SYS_PRCTL_H #include #endif #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "sshbuf.h" #include "ssherr.h" #include "log.h" #include "misc.h" #include "match.h" #include "uidswap.h" #include "sftp.h" #include "sftp-common.h" /* Our verbosity */ static LogLevel log_level = SYSLOG_LEVEL_ERROR; /* Our client */ static struct passwd *pw = NULL; static char *client_addr = NULL; /* input and output queue */ struct sshbuf *iqueue; struct sshbuf *oqueue; /* Version of client */ static u_int version; /* SSH2_FXP_INIT received */ static int init_done; /* Disable writes */ static int readonly; /* Requests that are allowed/denied */ static char *request_whitelist, *request_blacklist; /* portable attributes, etc. */ typedef struct Stat Stat; struct Stat { char *name; char *long_name; Attrib attrib; }; /* Packet handlers */ static void process_open(u_int32_t id); static void process_close(u_int32_t id); static void process_read(u_int32_t id); static void process_write(u_int32_t id); static void process_stat(u_int32_t id); static void process_lstat(u_int32_t id); static void process_fstat(u_int32_t id); static void process_setstat(u_int32_t id); static void process_fsetstat(u_int32_t id); static void process_opendir(u_int32_t id); static void process_readdir(u_int32_t id); static void process_remove(u_int32_t id); static void process_mkdir(u_int32_t id); static void process_rmdir(u_int32_t id); static void process_realpath(u_int32_t id); static void process_rename(u_int32_t id); static void process_readlink(u_int32_t id); static void process_symlink(u_int32_t id); static void process_extended_posix_rename(u_int32_t id); static void process_extended_statvfs(u_int32_t id); static void process_extended_fstatvfs(u_int32_t id); static void process_extended_hardlink(u_int32_t id); static void process_extended_fsync(u_int32_t id); static void process_extended(u_int32_t id); struct sftp_handler { const char *name; /* user-visible name for fine-grained perms */ const char *ext_name; /* extended request name */ u_int type; /* packet type, for non extended packets */ void (*handler)(u_int32_t); int does_write; /* if nonzero, banned for readonly mode */ }; struct sftp_handler handlers[] = { /* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */ { "open", NULL, SSH2_FXP_OPEN, process_open, 0 }, { "close", NULL, SSH2_FXP_CLOSE, process_close, 0 }, { "read", NULL, SSH2_FXP_READ, process_read, 0 }, { "write", NULL, SSH2_FXP_WRITE, process_write, 1 }, { "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 }, { "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 }, { "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 }, { "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 }, { "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 }, { "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 }, { "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 }, { "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 }, { "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 }, { "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 }, { "stat", NULL, SSH2_FXP_STAT, process_stat, 0 }, { "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 }, { "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 }, { "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 }, { NULL, NULL, 0, NULL, 0 } }; /* SSH2_FXP_EXTENDED submessages */ struct sftp_handler extended_handlers[] = { { "posix-rename", "posix-rename@openssh.com", 0, process_extended_posix_rename, 1 }, { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 }, { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 }, { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 }, { "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 }, { NULL, NULL, 0, NULL, 0 } }; static int request_permitted(struct sftp_handler *h) { char *result; if (readonly && h->does_write) { verbose("Refusing %s request in read-only mode", h->name); return 0; } if (request_blacklist != NULL && ((result = match_list(h->name, request_blacklist, NULL))) != NULL) { free(result); verbose("Refusing blacklisted %s request", h->name); return 0; } if (request_whitelist != NULL && ((result = match_list(h->name, request_whitelist, NULL))) != NULL) { free(result); debug2("Permitting whitelisted %s request", h->name); return 1; } if (request_whitelist != NULL) { verbose("Refusing non-whitelisted %s request", h->name); return 0; } return 1; } static int errno_to_portable(int unixerrno) { int ret = 0; switch (unixerrno) { case 0: ret = SSH2_FX_OK; break; case ENOENT: case ENOTDIR: case EBADF: case ELOOP: ret = SSH2_FX_NO_SUCH_FILE; break; case EPERM: case EACCES: case EFAULT: ret = SSH2_FX_PERMISSION_DENIED; break; case ENAMETOOLONG: case EINVAL: ret = SSH2_FX_BAD_MESSAGE; break; case ENOSYS: ret = SSH2_FX_OP_UNSUPPORTED; break; default: ret = SSH2_FX_FAILURE; break; } return ret; } static int flags_from_portable(int pflags) { int flags = 0; if ((pflags & SSH2_FXF_READ) && (pflags & SSH2_FXF_WRITE)) { flags = O_RDWR; } else if (pflags & SSH2_FXF_READ) { flags = O_RDONLY; } else if (pflags & SSH2_FXF_WRITE) { flags = O_WRONLY; } if (pflags & SSH2_FXF_APPEND) flags |= O_APPEND; if (pflags & SSH2_FXF_CREAT) flags |= O_CREAT; if (pflags & SSH2_FXF_TRUNC) flags |= O_TRUNC; if (pflags & SSH2_FXF_EXCL) flags |= O_EXCL; return flags; } static const char * string_from_portable(int pflags) { static char ret[128]; *ret = '\0'; #define PAPPEND(str) { \ if (*ret != '\0') \ strlcat(ret, ",", sizeof(ret)); \ strlcat(ret, str, sizeof(ret)); \ } if (pflags & SSH2_FXF_READ) PAPPEND("READ") if (pflags & SSH2_FXF_WRITE) PAPPEND("WRITE") if (pflags & SSH2_FXF_APPEND) PAPPEND("APPEND") if (pflags & SSH2_FXF_CREAT) PAPPEND("CREATE") if (pflags & SSH2_FXF_TRUNC) PAPPEND("TRUNCATE") if (pflags & SSH2_FXF_EXCL) PAPPEND("EXCL") return ret; } /* handle handles */ typedef struct Handle Handle; struct Handle { int use; DIR *dirp; int fd; int flags; char *name; u_int64_t bytes_read, bytes_write; int next_unused; }; enum { HANDLE_UNUSED, HANDLE_DIR, HANDLE_FILE }; Handle *handles = NULL; u_int num_handles = 0; int first_unused_handle = -1; static void handle_unused(int i) { handles[i].use = HANDLE_UNUSED; handles[i].next_unused = first_unused_handle; first_unused_handle = i; } static int handle_new(int use, const char *name, int fd, int flags, DIR *dirp) { int i; if (first_unused_handle == -1) { if (num_handles + 1 <= num_handles) return -1; num_handles++; handles = xreallocarray(handles, num_handles, sizeof(Handle)); handle_unused(num_handles - 1); } i = first_unused_handle; first_unused_handle = handles[i].next_unused; handles[i].use = use; handles[i].dirp = dirp; handles[i].fd = fd; handles[i].flags = flags; handles[i].name = xstrdup(name); handles[i].bytes_read = handles[i].bytes_write = 0; return i; } static int handle_is_ok(int i, int type) { return i >= 0 && (u_int)i < num_handles && handles[i].use == type; } static int handle_to_string(int handle, u_char **stringp, int *hlenp) { if (stringp == NULL || hlenp == NULL) return -1; *stringp = xmalloc(sizeof(int32_t)); put_u32(*stringp, handle); *hlenp = sizeof(int32_t); return 0; } static int handle_from_string(const u_char *handle, u_int hlen) { int val; if (hlen != sizeof(int32_t)) return -1; val = get_u32(handle); if (handle_is_ok(val, HANDLE_FILE) || handle_is_ok(val, HANDLE_DIR)) return val; return -1; } static char * handle_to_name(int handle) { if (handle_is_ok(handle, HANDLE_DIR)|| handle_is_ok(handle, HANDLE_FILE)) return handles[handle].name; return NULL; } static DIR * handle_to_dir(int handle) { if (handle_is_ok(handle, HANDLE_DIR)) return handles[handle].dirp; return NULL; } static int handle_to_fd(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) return handles[handle].fd; return -1; } static int handle_to_flags(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) return handles[handle].flags; return 0; } static void handle_update_read(int handle, ssize_t bytes) { if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) handles[handle].bytes_read += bytes; } static void handle_update_write(int handle, ssize_t bytes) { if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0) handles[handle].bytes_write += bytes; } static u_int64_t handle_bytes_read(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) return (handles[handle].bytes_read); return 0; } static u_int64_t handle_bytes_write(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) return (handles[handle].bytes_write); return 0; } static int handle_close(int handle) { int ret = -1; if (handle_is_ok(handle, HANDLE_FILE)) { ret = close(handles[handle].fd); free(handles[handle].name); handle_unused(handle); } else if (handle_is_ok(handle, HANDLE_DIR)) { ret = closedir(handles[handle].dirp); free(handles[handle].name); handle_unused(handle); } else { errno = ENOENT; } return ret; } static void handle_log_close(int handle, char *emsg) { if (handle_is_ok(handle, HANDLE_FILE)) { logit("%s%sclose \"%s\" bytes read %llu written %llu", emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", handle_to_name(handle), (unsigned long long)handle_bytes_read(handle), (unsigned long long)handle_bytes_write(handle)); } else { logit("%s%sclosedir \"%s\"", emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", handle_to_name(handle)); } } static void handle_log_exit(void) { u_int i; for (i = 0; i < num_handles; i++) if (handles[i].use != HANDLE_UNUSED) handle_log_close(i, "forced"); } static int get_handle(struct sshbuf *queue, int *hp) { u_char *handle; int r; size_t hlen; *hp = -1; if ((r = sshbuf_get_string(queue, &handle, &hlen)) != 0) return r; if (hlen < 256) *hp = handle_from_string(handle, hlen); free(handle); return 0; } /* send replies */ static void send_msg(struct sshbuf *m) { int r; if ((r = sshbuf_put_stringb(oqueue, m)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_reset(m); } static const char * status_to_message(u_int32_t status) { const char *status_messages[] = { "Success", /* SSH_FX_OK */ "End of file", /* SSH_FX_EOF */ "No such file", /* SSH_FX_NO_SUCH_FILE */ "Permission denied", /* SSH_FX_PERMISSION_DENIED */ "Failure", /* SSH_FX_FAILURE */ "Bad message", /* SSH_FX_BAD_MESSAGE */ "No connection", /* SSH_FX_NO_CONNECTION */ "Connection lost", /* SSH_FX_CONNECTION_LOST */ "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ "Unknown error" /* Others */ }; return (status_messages[MIN(status,SSH2_FX_MAX)]); } static void send_status(u_int32_t id, u_int32_t status) { struct sshbuf *msg; int r; debug3("request %u: sent status %u", id, status); if (log_level > SYSLOG_LEVEL_VERBOSE || (status != SSH2_FX_OK && status != SSH2_FX_EOF)) logit("sent status %s", status_to_message(status)); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_STATUS)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_u32(msg, status)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (version >= 3) { if ((r = sshbuf_put_cstring(msg, status_to_message(status))) != 0 || (r = sshbuf_put_cstring(msg, "")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } send_msg(msg); sshbuf_free(msg); } static void send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) { struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, type)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_string(msg, data, dlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_free(msg); } static void send_data(u_int32_t id, const u_char *data, int dlen) { debug("request %u: sent data len %d", id, dlen); send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); } static void send_handle(u_int32_t id, int handle) { u_char *string; int hlen; handle_to_string(handle, &string, &hlen); debug("request %u: sent handle handle %d", id, handle); send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); free(string); } static void send_names(u_int32_t id, int count, const Stat *stats) { struct sshbuf *msg; int i, r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_u32(msg, count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: sent names count %d", id, count); for (i = 0; i < count; i++) { if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 || (r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 || (r = encode_attrib(msg, &stats[i].attrib)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } send_msg(msg); sshbuf_free(msg); } static void send_attrib(u_int32_t id, const Attrib *a) { struct sshbuf *msg; int r; debug("request %u: sent attrib have 0x%x", id, a->flags); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = encode_attrib(msg, a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_free(msg); } static void send_statvfs(u_int32_t id, struct statvfs *st) { struct sshbuf *msg; u_int64_t flag; int r; flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 || (r = sshbuf_put_u32(msg, id)) != 0 || (r = sshbuf_put_u64(msg, st->f_bsize)) != 0 || (r = sshbuf_put_u64(msg, st->f_frsize)) != 0 || (r = sshbuf_put_u64(msg, st->f_blocks)) != 0 || (r = sshbuf_put_u64(msg, st->f_bfree)) != 0 || (r = sshbuf_put_u64(msg, st->f_bavail)) != 0 || (r = sshbuf_put_u64(msg, st->f_files)) != 0 || (r = sshbuf_put_u64(msg, st->f_ffree)) != 0 || (r = sshbuf_put_u64(msg, st->f_favail)) != 0 || (r = sshbuf_put_u64(msg, FSID_TO_ULONG(st->f_fsid))) != 0 || (r = sshbuf_put_u64(msg, flag)) != 0 || (r = sshbuf_put_u64(msg, st->f_namemax)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_free(msg); } /* parse incoming */ static void process_init(void) { struct sshbuf *msg; int r; if ((r = sshbuf_get_u32(iqueue, &version)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); verbose("received client version %u", version); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 || (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0 || /* POSIX rename extension */ (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ /* statvfs extension */ (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ /* fstatvfs extension */ (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ /* hardlink extension */ (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ /* fsync extension */ (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || (r = sshbuf_put_cstring(msg, "1")) != 0) /* version */ fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_free(msg); } static void process_open(u_int32_t id) { u_int32_t pflags; Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) { verbose("Refusing open request in read-only mode"); status = SSH2_FX_PERMISSION_DENIED; } else { fd = open(name, flags, mode); if (fd < 0) { status = errno_to_portable(errno); } else { handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); if (handle < 0) { close(fd); } else { send_handle(id, handle); status = SSH2_FX_OK; } } } if (status != SSH2_FX_OK) send_status(id, status); free(name); } static void process_close(u_int32_t id) { int r, handle, ret, status = SSH2_FX_FAILURE; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: close handle %u", id, handle); handle_log_close(handle, NULL); ret = handle_close(handle); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); } static void process_read(u_int32_t id) { u_char buf[64*1024]; u_int32_t len; int r, handle, fd, ret, status = SSH2_FX_FAILURE; u_int64_t off; if ((r = get_handle(iqueue, &handle)) != 0 || (r = sshbuf_get_u64(iqueue, &off)) != 0 || (r = sshbuf_get_u32(iqueue, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: read \"%s\" (handle %d) off %llu len %d", id, handle_to_name(handle), handle, (unsigned long long)off, len); if (len > sizeof buf) { len = sizeof buf; debug2("read change len %d", len); } fd = handle_to_fd(handle); if (fd >= 0) { if (lseek(fd, off, SEEK_SET) < 0) { error("process_read: seek failed"); status = errno_to_portable(errno); } else { ret = read(fd, buf, len); if (ret < 0) { status = errno_to_portable(errno); } else if (ret == 0) { status = SSH2_FX_EOF; } else { send_data(id, buf, ret); status = SSH2_FX_OK; handle_update_read(handle, ret); } } } if (status != SSH2_FX_OK) send_status(id, status); } static void process_write(u_int32_t id) { u_int64_t off; size_t len; int r, handle, fd, ret, status; u_char *data; if ((r = get_handle(iqueue, &handle)) != 0 || (r = sshbuf_get_u64(iqueue, &off)) != 0 || (r = sshbuf_get_string(iqueue, &data, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; else { if (!(handle_to_flags(handle) & O_APPEND) && lseek(fd, off, SEEK_SET) < 0) { status = errno_to_portable(errno); error("process_write: seek failed"); } else { /* XXX ATOMICIO ? */ ret = write(fd, data, len); if (ret < 0) { error("process_write: write failed"); status = errno_to_portable(errno); } else if ((size_t)ret == len) { status = SSH2_FX_OK; handle_update_write(handle, ret); } else { debug2("nothing at all written"); status = SSH2_FX_FAILURE; } } } send_status(id, status); free(data); } static void process_do_stat(u_int32_t id, int do_lstat) { Attrib a; struct stat st; char *name; int r, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); r = do_lstat ? lstat(name, &st) : stat(name, &st); if (r < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); send_attrib(id, &a); status = SSH2_FX_OK; } if (status != SSH2_FX_OK) send_status(id, status); free(name); } static void process_stat(u_int32_t id) { process_do_stat(id, 0); } static void process_lstat(u_int32_t id) { process_do_stat(id, 1); } static void process_fstat(u_int32_t id) { Attrib a; struct stat st; int fd, r, handle, status = SSH2_FX_FAILURE; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); if (fd >= 0) { r = fstat(fd, &st); if (r < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); send_attrib(id, &a); status = SSH2_FX_OK; } } if (status != SSH2_FX_OK) send_status(id, status); } static struct timeval * attrib_to_tv(const Attrib *a) { static struct timeval tv[2]; tv[0].tv_sec = a->atime; tv[0].tv_usec = 0; tv[1].tv_sec = a->mtime; tv[1].tv_usec = 0; return tv; } static void process_setstat(u_int32_t id) { Attrib a; char *name; int r, status = SSH2_FX_OK; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: setstat name \"%s\"", id, name); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a.size); r = truncate(name, a.size); if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a.perm); r = chmod(name, a.perm & 07777); if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; time_t t = a.mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); r = utimes(name, attrib_to_tv(&a)); if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, (u_long)a.uid, (u_long)a.gid); r = chown(name, a.uid, a.gid); if (r == -1) status = errno_to_portable(errno); } send_status(id, status); free(name); } static void process_fsetstat(u_int32_t id) { Attrib a; int handle, fd, r; int status = SSH2_FX_OK; if ((r = get_handle(iqueue, &handle)) != 0 || (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; else { char *name = handle_to_name(handle); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a.size); r = ftruncate(fd, a.size); if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a.perm); #ifdef HAVE_FCHMOD r = fchmod(fd, a.perm & 07777); #else r = chmod(name, a.perm & 07777); #endif if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; time_t t = a.mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); #ifdef HAVE_FUTIMES r = futimes(fd, attrib_to_tv(&a)); #else r = utimes(name, attrib_to_tv(&a)); #endif if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, (u_long)a.uid, (u_long)a.gid); #ifdef HAVE_FCHOWN r = fchown(fd, a.uid, a.gid); #else r = chown(name, a.uid, a.gid); #endif if (r == -1) status = errno_to_portable(errno); } } send_status(id, status); } static void process_opendir(u_int32_t id) { DIR *dirp = NULL; char *path; int r, handle, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: opendir", id); logit("opendir \"%s\"", path); dirp = opendir(path); if (dirp == NULL) { status = errno_to_portable(errno); } else { handle = handle_new(HANDLE_DIR, path, 0, 0, dirp); if (handle < 0) { closedir(dirp); } else { send_handle(id, handle); status = SSH2_FX_OK; } } if (status != SSH2_FX_OK) send_status(id, status); free(path); } static void process_readdir(u_int32_t id) { DIR *dirp; struct dirent *dp; char *path; int r, handle; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: readdir \"%s\" (handle %d)", id, handle_to_name(handle), handle); dirp = handle_to_dir(handle); path = handle_to_name(handle); if (dirp == NULL || path == NULL) { send_status(id, SSH2_FX_FAILURE); } else { struct stat st; char pathname[PATH_MAX]; Stat *stats; int nstats = 10, count = 0, i; stats = xcalloc(nstats, sizeof(Stat)); while ((dp = readdir(dirp)) != NULL) { if (count >= nstats) { nstats *= 2; stats = xreallocarray(stats, nstats, sizeof(Stat)); } /* XXX OVERFLOW ? */ snprintf(pathname, sizeof pathname, "%s%s%s", path, strcmp(path, "/") ? "/" : "", dp->d_name); if (lstat(pathname, &st) < 0) continue; stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); count++; /* send up to 100 entries in one message */ /* XXX check packet size instead */ if (count == 100) break; } if (count > 0) { send_names(id, count, stats); for (i = 0; i < count; i++) { free(stats[i].name); free(stats[i].long_name); } } else { send_status(id, SSH2_FX_EOF); } free(stats); } } static void process_remove(u_int32_t id) { char *name; int r, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: remove", id); logit("remove name \"%s\"", name); r = unlink(name); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void process_mkdir(u_int32_t id) { Attrib a; char *name; int r, mode, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); r = mkdir(name, mode); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void process_rmdir(u_int32_t id) { char *name; int r, status; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); r = rmdir(name); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } static void process_realpath(u_int32_t id) { char resolvedname[PATH_MAX]; char *path; int r; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (path[0] == '\0') { free(path); path = xstrdup("."); } debug3("request %u: realpath", id); verbose("realpath \"%s\"", path); if (realpath(path, resolvedname) == NULL) { send_status(id, errno_to_portable(errno)); } else { Stat s; attrib_clear(&s.attrib); s.name = s.long_name = resolvedname; send_names(id, 1, &s); } free(path); } static void process_rename(u_int32_t id) { char *oldpath, *newpath; int r, status; struct stat sb; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; if (lstat(oldpath, &sb) == -1) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ if (link(oldpath, newpath) == -1) { if (errno == EOPNOTSUPP || errno == ENOSYS #ifdef EXDEV || errno == EXDEV #endif #ifdef LINK_OPNOTSUPP_ERRNO || errno == LINK_OPNOTSUPP_ERRNO #endif ) { struct stat st; /* * fs doesn't support links, so fall back to * stat+rename. This is racy. */ if (stat(newpath, &st) == -1) { if (rename(oldpath, newpath) == -1) status = errno_to_portable(errno); else status = SSH2_FX_OK; } } else { status = errno_to_portable(errno); } } else if (unlink(oldpath) == -1) { status = errno_to_portable(errno); /* clean spare link */ unlink(newpath); } else status = SSH2_FX_OK; } else if (stat(newpath, &sb) == -1) { if (rename(oldpath, newpath) == -1) status = errno_to_portable(errno); else status = SSH2_FX_OK; } send_status(id, status); free(oldpath); free(newpath); } static void process_readlink(u_int32_t id) { int r, len; char buf[PATH_MAX]; char *path; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) send_status(id, errno_to_portable(errno)); else { Stat s; buf[len] = '\0'; attrib_clear(&s.attrib); s.name = s.long_name = buf; send_names(id, 1, &s); } free(path); } static void process_symlink(u_int32_t id) { char *oldpath, *newpath; int r, status; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ r = symlink(oldpath, newpath); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); } static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; int r, status; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); r = rename(oldpath, newpath); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); } static void process_extended_statvfs(u_int32_t id) { char *path; struct statvfs st; int r; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: statvfs", id); logit("statvfs \"%s\"", path); if (statvfs(path, &st) != 0) send_status(id, errno_to_portable(errno)); else send_statvfs(id, &st); free(path); } static void process_extended_fstatvfs(u_int32_t id) { int r, handle, fd; struct statvfs st; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { send_status(id, SSH2_FX_FAILURE); return; } if (fstatvfs(fd, &st) != 0) send_status(id, errno_to_portable(errno)); else send_statvfs(id, &st); } static void process_extended_hardlink(u_int32_t id) { char *oldpath, *newpath; int r, status; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: hardlink", id); logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); r = link(oldpath, newpath); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); } static void process_extended_fsync(u_int32_t id) { int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: fsync (handle %u)", id, handle); verbose("fsync \"%s\"", handle_to_name(handle)); if ((fd = handle_to_fd(handle)) < 0) status = SSH2_FX_NO_SUCH_FILE; else if (handle_is_ok(handle, HANDLE_FILE)) { r = fsync(fd); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); } static void process_extended(u_int32_t id) { char *request; int i, r; if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; extended_handlers[i].handler != NULL; i++) { if (strcmp(request, extended_handlers[i].ext_name) == 0) { if (!request_permitted(&extended_handlers[i])) send_status(id, SSH2_FX_PERMISSION_DENIED); else extended_handlers[i].handler(id); break; } } if (extended_handlers[i].handler == NULL) { error("Unknown extended request \"%.100s\"", request); send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ } free(request); } /* stolen from ssh-agent */ static void process(void) { u_int msg_len; u_int buf_len; u_int consumed; u_char type; const u_char *cp; int i, r; u_int32_t id; buf_len = sshbuf_len(iqueue); if (buf_len < 5) return; /* Incomplete message. */ cp = sshbuf_ptr(iqueue); msg_len = get_u32(cp); if (msg_len > SFTP_MAX_MSG_LENGTH) { error("bad message from %s local user %s", client_addr, pw->pw_name); sftp_server_cleanup_exit(11); } if (buf_len < msg_len + 4) return; if ((r = sshbuf_consume(iqueue, 4)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); buf_len -= 4; if ((r = sshbuf_get_u8(iqueue, &type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); switch (type) { case SSH2_FXP_INIT: process_init(); init_done = 1; break; case SSH2_FXP_EXTENDED: if (!init_done) fatal("Received extended request before init"); if ((r = sshbuf_get_u32(iqueue, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); process_extended(id); break; default: if (!init_done) fatal("Received %u request before init", type); if ((r = sshbuf_get_u32(iqueue, &id)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; handlers[i].handler != NULL; i++) { if (type == handlers[i].type) { if (!request_permitted(&handlers[i])) { send_status(id, SSH2_FX_PERMISSION_DENIED); } else { handlers[i].handler(id); } break; } } if (handlers[i].handler == NULL) error("Unknown message %u", type); } /* discard the remaining bytes from the current packet */ if (buf_len < sshbuf_len(iqueue)) { error("iqueue grew unexpectedly"); sftp_server_cleanup_exit(255); } consumed = buf_len - sshbuf_len(iqueue); if (msg_len < consumed) { error("msg_len %u < consumed %u", msg_len, consumed); sftp_server_cleanup_exit(255); } if (msg_len > consumed && (r = sshbuf_consume(iqueue, msg_len - consumed)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } /* Cleanup handler that logs active handles upon normal exit */ void sftp_server_cleanup_exit(int i) { if (pw != NULL && client_addr != NULL) { handle_log_exit(); logit("session closed for local user %s from [%s]", pw->pw_name, client_addr); } _exit(i); } static void sftp_server_usage(void) { extern char *__progname; fprintf(stderr, "usage: %s [-ehR] [-d start_directory] [-f log_facility] " "[-l log_level]\n\t[-P blacklisted_requests] " "[-p whitelisted_requests] [-u umask]\n" " %s -Q protocol_feature\n", __progname, __progname); exit(1); } int sftp_server_main(int argc, char **argv, struct passwd *user_pw) { fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, *homedir = NULL, buf[4*4096]; long mask; extern char *optarg; extern char *__progname; ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); pw = pwcopy(user_pw); while (!skipargs && (ch = getopt(argc, argv, "d:f:l:P:p:Q:u:cehR")) != -1) { switch (ch) { case 'Q': if (strcasecmp(optarg, "requests") != 0) { fprintf(stderr, "Invalid query type\n"); exit(1); } for (i = 0; handlers[i].handler != NULL; i++) printf("%s\n", handlers[i].name); for (i = 0; extended_handlers[i].handler != NULL; i++) printf("%s\n", extended_handlers[i].name); exit(0); break; case 'R': readonly = 1; break; case 'c': /* * Ignore all arguments if we are invoked as a * shell using "sftp-server -c command" */ skipargs = 1; break; case 'e': log_stderr = 1; break; case 'l': log_level = log_level_number(optarg); if (log_level == SYSLOG_LEVEL_NOT_SET) error("Invalid log level \"%s\"", optarg); break; case 'f': log_facility = log_facility_number(optarg); if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; case 'd': cp = tilde_expand_filename(optarg, user_pw->pw_uid); homedir = percent_expand(cp, "d", user_pw->pw_dir, "u", user_pw->pw_name, (char *)NULL); free(cp); break; case 'p': if (request_whitelist != NULL) fatal("Permitted requests already set"); request_whitelist = xstrdup(optarg); break; case 'P': if (request_blacklist != NULL) fatal("Refused requests already set"); request_blacklist = xstrdup(optarg); break; case 'u': errno = 0; mask = strtol(optarg, &cp, 8); if (mask < 0 || mask > 0777 || *cp != '\0' || cp == optarg || (mask == 0 && errno != 0)) fatal("Invalid umask \"%s\"", optarg); (void)umask((mode_t)mask); break; case 'h': default: sftp_server_usage(); } } log_init(__progname, log_level, log_facility, log_stderr); #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* * On Linux, we should try to avoid making /proc/self/{mem,maps} * available to the user so that sftp access doesn't automatically * imply arbitrary code execution access that will break * restricted configurations. */ if (prctl(PR_SET_DUMPABLE, 0) != 0) fatal("unable to make the process undumpable"); #endif /* defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) */ /* Drop any fine-grained privileges we don't need */ platform_pledge_sftp_server(); if ((cp = getenv("SSH_CONNECTION")) != NULL) { client_addr = xstrdup(cp); if ((cp = strchr(client_addr, ' ')) == NULL) { error("Malformed SSH_CONNECTION variable: \"%s\"", getenv("SSH_CONNECTION")); sftp_server_cleanup_exit(255); } *cp = '\0'; } else client_addr = xstrdup("UNKNOWN"); logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); in = STDIN_FILENO; out = STDOUT_FILENO; #ifdef HAVE_CYGWIN setmode(in, O_BINARY); setmode(out, O_BINARY); #endif max = 0; if (in > max) max = in; if (out > max) max = out; if ((iqueue = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((oqueue = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); if (homedir != NULL) { if (chdir(homedir) != 0) { error("chdir to \"%s\" failed: %s", homedir, strerror(errno)); } } set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); for (;;) { memset(rset, 0, set_size); memset(wset, 0, set_size); /* * Ensure that we can read a full buffer and handle * the worst-case length packet it can generate, * otherwise apply backpressure by stopping reads. */ if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && (r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH)) == 0) FD_SET(in, rset); else if (r != SSH_ERR_NO_BUFFER_SPACE) fatal("%s: sshbuf_check_reserve failed: %s", __func__, ssh_err(r)); olen = sshbuf_len(oqueue); if (olen > 0) FD_SET(out, wset); if (select(max+1, rset, wset, NULL, NULL) < 0) { if (errno == EINTR) continue; error("select: %s", strerror(errno)); sftp_server_cleanup_exit(2); } /* copy stdin to iqueue */ if (FD_ISSET(in, rset)) { len = read(in, buf, sizeof buf); if (len == 0) { debug("read eof"); sftp_server_cleanup_exit(0); } else if (len < 0) { error("read: %s", strerror(errno)); sftp_server_cleanup_exit(1); } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) { fatal("%s: buffer error: %s", __func__, ssh_err(r)); } } /* send oqueue to stdout */ if (FD_ISSET(out, wset)) { len = write(out, sshbuf_ptr(oqueue), olen); if (len < 0) { error("write: %s", strerror(errno)); sftp_server_cleanup_exit(1); } else if ((r = sshbuf_consume(oqueue, len)) != 0) { fatal("%s: buffer error: %s", __func__, ssh_err(r)); } } /* * Process requests from client if we can fit the results * into the output buffer, otherwise stop processing input * and let the output queue drain. */ r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH); if (r == 0) process(); else if (r != SSH_ERR_NO_BUFFER_SPACE) fatal("%s: sshbuf_check_reserve: %s", __func__, ssh_err(r)); } } openssh-7.2p2/sftp.1010064400017500001750000000347421267006270000125220ustar00djmdjm.\" $OpenBSD: sftp.1,v 1.102 2015/09/25 18:19:54 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" 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. .\" .Dd $Mdocdate: September 25 2015 $ .Dt SFTP 1 .Os .Sh NAME .Nm sftp .Nd secure file transfer program .Sh SYNOPSIS .Nm sftp .Bk -words .Op Fl 1246aCfpqrv .Op Fl B Ar buffer_size .Op Fl b Ar batchfile .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config .Op Fl i Ar identity_file .Op Fl l Ar limit .Op Fl o Ar ssh_option .Op Fl P Ar port .Op Fl R Ar num_requests .Op Fl S Ar program .Op Fl s Ar subsystem | sftp_server .Ar host .Ek .Nm sftp .Oo Ar user Ns @ Oc Ns .Ar host Ns Op : Ns Ar .Nm sftp .Oo .Ar user Ns @ Oc Ns .Ar host Ns Oo : Ns Ar dir Ns .Op Ar / .Oc .Nm sftp .Fl b Ar batchfile .Oo Ar user Ns @ Oc Ns Ar host .Sh DESCRIPTION .Nm is an interactive file transfer program, similar to .Xr ftp 1 , which performs all operations over an encrypted .Xr ssh 1 transport. It may also use many features of ssh, such as public key authentication and compression. .Nm connects and logs into the specified .Ar host , then enters an interactive command mode. .Pp The second usage format will retrieve files automatically if a non-interactive authentication method is used; otherwise it will do so after successful interactive authentication. .Pp The third usage format allows .Nm to start in a remote directory. .Pp The final usage format allows for automated sessions using the .Fl b option. In such cases, it is necessary to configure non-interactive authentication to obviate the need to enter a password at connection time (see .Xr sshd 8 and .Xr ssh-keygen 1 for details). .Pp Since some usage formats use colon characters to delimit host names from path names, IPv6 addresses must be enclosed in square brackets to avoid ambiguity. .Pp The options are as follows: .Bl -tag -width Ds .It Fl 1 Specify the use of protocol version 1. .It Fl 2 Specify the use of protocol version 2. .It Fl 4 Forces .Nm to use IPv4 addresses only. .It Fl 6 Forces .Nm to use IPv6 addresses only. .It Fl a Attempt to continue interrupted transfers rather than overwriting existing partial or complete copies of files. If the partial contents differ from those being transferred, then the resultant file is likely to be corrupt. .It Fl B Ar buffer_size Specify the size of the buffer that .Nm uses when transferring files. Larger buffers require fewer round trips at the cost of higher memory consumption. The default is 32768 bytes. .It Fl b Ar batchfile Batch mode reads a series of commands from an input .Ar batchfile instead of .Em stdin . Since it lacks user interaction it should be used in conjunction with non-interactive authentication. A .Ar batchfile of .Sq \- may be used to indicate standard input. .Nm will abort if any of the following commands fail: .Ic get , put , reget , reput, rename , ln , .Ic rm , mkdir , chdir , ls , .Ic lchdir , chmod , chown , .Ic chgrp , lpwd , df , symlink , and .Ic lmkdir . Termination on error can be suppressed on a command by command basis by prefixing the command with a .Sq \- character (for example, .Ic -rm /tmp/blah* ) . .It Fl C Enables compression (via ssh's .Fl C flag). .It Fl c Ar cipher Selects the cipher to use for encrypting the data transfers. This option is directly passed to .Xr ssh 1 . .It Fl D Ar sftp_server_path Connect directly to a local sftp server (rather than via .Xr ssh 1 ) . This option may be useful in debugging the client and server. .It Fl F Ar ssh_config Specifies an alternative per-user configuration file for .Xr ssh 1 . This option is directly passed to .Xr ssh 1 . .It Fl f Requests that files be flushed to disk immediately after transfer. When uploading files, this feature is only enabled if the server implements the "fsync@openssh.com" extension. .It Fl i Ar identity_file Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to .Xr ssh 1 . .It Fl l Ar limit Limits the used bandwidth, specified in Kbit/s. .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh in the format used in .Xr ssh_config 5 . This is useful for specifying options for which there is no separate .Nm sftp command-line flag. For example, to specify an alternate port use: .Ic sftp -oPort=24 . For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact .It AddressFamily .It BatchMode .It BindAddress .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs .It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher .It Ciphers .It Compression .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout .It ControlMaster .It ControlPath .It ControlPersist .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials .It HashKnownHosts .It Host .It HostbasedAuthentication .It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName .It IdentityFile .It IdentitiesOnly .It IPQoS .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication .It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol .It ProxyCommand .It PubkeyAuthentication .It RekeyLimit .It RhostsRSAAuthentication .It RSAAuthentication .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It StrictHostKeyChecking .It TCPKeepAlive .It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile .It VerifyHostKeyDNS .El .It Fl P Ar port Specifies the port to connect to on the remote host. .It Fl p Preserves modification times, access times, and modes from the original files transferred. .It Fl q Quiet mode: disables the progress meter as well as warning and diagnostic messages from .Xr ssh 1 . .It Fl R Ar num_requests Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. The default is 64 outstanding requests. .It Fl r Recursively copy entire directories when uploading and downloading. Note that .Nm does not follow symbolic links encountered in the tree traversal. .It Fl S Ar program Name of the .Ar program to use for the encrypted connection. The program must understand .Xr ssh 1 options. .It Fl s Ar subsystem | sftp_server Specifies the SSH2 subsystem or the path for an sftp server on the remote host. A path is useful for using .Nm over protocol version 1, or when the remote .Xr sshd 8 does not have an sftp subsystem configured. .It Fl v Raise logging level. This option is also passed to ssh. .El .Sh INTERACTIVE COMMANDS Once in interactive mode, .Nm understands a set of commands similar to those of .Xr ftp 1 . Commands are case insensitive. Pathnames that contain spaces must be enclosed in quotes. Any special characters contained within pathnames that are recognized by .Xr glob 3 must be escaped with backslashes .Pq Sq \e . .Bl -tag -width Ds .It Ic bye Quit .Nm sftp . .It Ic cd Ar path Change remote directory to .Ar path . .It Ic chgrp Ar grp Ar path Change group of file .Ar path to .Ar grp . .Ar path may contain .Xr glob 3 characters and may match multiple files. .Ar grp must be a numeric GID. .It Ic chmod Ar mode Ar path Change permissions of file .Ar path to .Ar mode . .Ar path may contain .Xr glob 3 characters and may match multiple files. .It Ic chown Ar own Ar path Change owner of file .Ar path to .Ar own . .Ar path may contain .Xr glob 3 characters and may match multiple files. .Ar own must be a numeric UID. .It Xo Ic df .Op Fl hi .Op Ar path .Xc Display usage information for the filesystem holding the current directory (or .Ar path if specified). If the .Fl h flag is specified, the capacity information will be displayed using "human-readable" suffixes. The .Fl i flag requests display of inode information in addition to capacity information. This command is only supported on servers that implement the .Dq statvfs@openssh.com extension. .It Ic exit Quit .Nm sftp . .It Xo Ic get .Op Fl afPpr .Ar remote-path .Op Ar local-path .Xc Retrieve the .Ar remote-path and store it on the local machine. If the local path name is not specified, it is given the same name it has on the remote machine. .Ar remote-path may contain .Xr glob 3 characters and may match multiple files. If it does and .Ar local-path is specified, then .Ar local-path must specify a directory. .Pp If the .Fl a flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the local file matches the remote copy. If the remote file contents differ from the partial local copy then the resultant file is likely to be corrupt. .Pp If the .Fl f flag is specified, then .Xr fsync 2 will be called after the file transfer has completed to flush the file to disk. .Pp If either the .Fl P or .Fl p flag is specified, then full file permissions and access times are copied too. .Pp If the .Fl r flag is specified then directories will be copied recursively. Note that .Nm does not follow symbolic links when performing recursive transfers. .It Ic help Display help text. .It Ic lcd Ar path Change local directory to .Ar path . .It Ic lls Op Ar ls-options Op Ar path Display local directory listing of either .Ar path or current directory if .Ar path is not specified. .Ar ls-options may contain any flags supported by the local system's .Xr ls 1 command. .Ar path may contain .Xr glob 3 characters and may match multiple files. .It Ic lmkdir Ar path Create local directory specified by .Ar path . .It Xo Ic ln .Op Fl s .Ar oldpath .Ar newpath .Xc Create a link from .Ar oldpath to .Ar newpath . If the .Fl s flag is specified the created link is a symbolic link, otherwise it is a hard link. .It Ic lpwd Print local working directory. .It Xo Ic ls .Op Fl 1afhlnrSt .Op Ar path .Xc Display a remote directory listing of either .Ar path or the current directory if .Ar path is not specified. .Ar path may contain .Xr glob 3 characters and may match multiple files. .Pp The following flags are recognized and alter the behaviour of .Ic ls accordingly: .Bl -tag -width Ds .It Fl 1 Produce single columnar output. .It Fl a List files beginning with a dot .Pq Sq \&. . .It Fl f Do not sort the listing. The default sort order is lexicographical. .It Fl h When used with a long format option, use unit suffixes: Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce the number of digits to four or fewer using powers of 2 for sizes (K=1024, M=1048576, etc.). .It Fl l Display additional details including permissions and ownership information. .It Fl n Produce a long listing with user and group information presented numerically. .It Fl r Reverse the sort order of the listing. .It Fl S Sort the listing by file size. .It Fl t Sort the listing by last modification time. .El .It Ic lumask Ar umask Set local umask to .Ar umask . .It Ic mkdir Ar path Create remote directory specified by .Ar path . .It Ic progress Toggle display of progress meter. .It Xo Ic put .Op Fl afPpr .Ar local-path .Op Ar remote-path .Xc Upload .Ar local-path and store it on the remote machine. If the remote path name is not specified, it is given the same name it has on the local machine. .Ar local-path may contain .Xr glob 3 characters and may match multiple files. If it does and .Ar remote-path is specified, then .Ar remote-path must specify a directory. .Pp If the .Fl a flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the remote file matches the local copy. If the local file contents differ from the remote local copy then the resultant file is likely to be corrupt. .Pp If the .Fl f flag is specified, then a request will be sent to the server to call .Xr fsync 2 after the file has been transferred. Note that this is only supported by servers that implement the "fsync@openssh.com" extension. .Pp If either the .Fl P or .Fl p flag is specified, then full file permissions and access times are copied too. .Pp If the .Fl r flag is specified then directories will be copied recursively. Note that .Nm does not follow symbolic links when performing recursive transfers. .It Ic pwd Display remote working directory. .It Ic quit Quit .Nm sftp . .It Xo Ic reget .Op Fl Ppr .Ar remote-path .Op Ar local-path .Xc Resume download of .Ar remote-path . Equivalent to .Ic get with the .Fl a flag set. .It Xo Ic reput .Op Fl Ppr .Op Ar local-path .Ar remote-path .Xc Resume upload of .Op Ar local-path . Equivalent to .Ic put with the .Fl a flag set. .It Ic rename Ar oldpath Ar newpath Rename remote file from .Ar oldpath to .Ar newpath . .It Ic rm Ar path Delete remote file specified by .Ar path . .It Ic rmdir Ar path Remove remote directory specified by .Ar path . .It Ic symlink Ar oldpath Ar newpath Create a symbolic link from .Ar oldpath to .Ar newpath . .It Ic version Display the .Nm protocol version. .It Ic \&! Ns Ar command Execute .Ar command in local shell. .It Ic \&! Escape to local shell. .It Ic \&? Synonym for help. .El .Sh SEE ALSO .Xr ftp 1 , .Xr ls 1 , .Xr scp 1 , .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-keygen 1 , .Xr glob 3 , .Xr ssh_config 5 , .Xr sftp-server 8 , .Xr sshd 8 .Rs .%A T. Ylonen .%A S. Lehtinen .%T "SSH File Transfer Protocol" .%N draft-ietf-secsh-filexfer-00.txt .%D January 2001 .%O work in progress material .Re openssh-7.2p2/sftp.c010064400017500001750000001613241267006270000126010ustar00djmdjm/* $OpenBSD: sftp.c,v 1.172 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 /* MIN MAX */ #include #include #ifdef HAVE_SYS_STAT_H # include #endif #include #include #include #ifdef HAVE_SYS_STATVFS_H #include #endif #include #include #ifdef HAVE_PATHS_H # include #endif #ifdef HAVE_LIBGEN_H #include #endif #ifdef HAVE_LOCALE_H # include #endif #ifdef USE_LIBEDIT #include #else typedef void EditLine; #endif #include #include #include #include #include #include #include #ifdef HAVE_UTIL_H # include #endif #include "xmalloc.h" #include "log.h" #include "pathnames.h" #include "misc.h" #include "sftp.h" #include "ssherr.h" #include "sshbuf.h" #include "sftp-common.h" #include "sftp-client.h" #define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ #define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ /* File to read commands from */ FILE* infile; /* Are we in batchfile mode? */ int batchmode = 0; /* PID of ssh transport process */ static pid_t sshpid = -1; /* Suppress diagnositic messages */ int quiet = 0; /* This is set to 0 if the progressmeter is not desired. */ int showprogress = 1; /* When this option is set, we always recursively download/upload directories */ int global_rflag = 0; /* When this option is set, we resume download or upload if possible */ int global_aflag = 0; /* When this option is set, the file transfers will always preserve times */ int global_pflag = 0; /* When this option is set, transfers will have fsync() called on each file */ int global_fflag = 0; /* SIGINT received during command processing */ volatile sig_atomic_t interrupted = 0; /* I wish qsort() took a separate ctx for the comparison function...*/ int sort_flag; /* Context used for commandline completion */ struct complete_ctx { struct sftp_conn *conn; char **remote_pathp; }; int remote_glob(struct sftp_conn *, const char *, int, int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ extern char *__progname; /* Separators for interactive commands */ #define WHITESPACE " \t\r\n" /* ls flags */ #define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */ #define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */ #define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */ #define LS_NAME_SORT 0x0008 /* Sort by name (default) */ #define LS_TIME_SORT 0x0010 /* Sort by mtime */ #define LS_SIZE_SORT 0x0020 /* Sort by file size */ #define LS_REVERSE_SORT 0x0040 /* Reverse sort order */ #define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */ #define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */ #define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS) #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) /* Commands for interactive mode */ enum sftp_command { I_CHDIR = 1, I_CHGRP, I_CHMOD, I_CHOWN, I_DF, I_GET, I_HELP, I_LCHDIR, I_LINK, I_LLS, I_LMKDIR, I_LPWD, I_LS, I_LUMASK, I_MKDIR, I_PUT, I_PWD, I_QUIT, I_REGET, I_RENAME, I_REPUT, I_RM, I_RMDIR, I_SHELL, I_SYMLINK, I_VERSION, I_PROGRESS, }; struct CMD { const char *c; const int n; const int t; }; /* Type of completion */ #define NOARGS 0 #define REMOTE 1 #define LOCAL 2 static const struct CMD cmds[] = { { "bye", I_QUIT, NOARGS }, { "cd", I_CHDIR, REMOTE }, { "chdir", I_CHDIR, REMOTE }, { "chgrp", I_CHGRP, REMOTE }, { "chmod", I_CHMOD, REMOTE }, { "chown", I_CHOWN, REMOTE }, { "df", I_DF, REMOTE }, { "dir", I_LS, REMOTE }, { "exit", I_QUIT, NOARGS }, { "get", I_GET, REMOTE }, { "help", I_HELP, NOARGS }, { "lcd", I_LCHDIR, LOCAL }, { "lchdir", I_LCHDIR, LOCAL }, { "lls", I_LLS, LOCAL }, { "lmkdir", I_LMKDIR, LOCAL }, { "ln", I_LINK, REMOTE }, { "lpwd", I_LPWD, LOCAL }, { "ls", I_LS, REMOTE }, { "lumask", I_LUMASK, NOARGS }, { "mkdir", I_MKDIR, REMOTE }, { "mget", I_GET, REMOTE }, { "mput", I_PUT, LOCAL }, { "progress", I_PROGRESS, NOARGS }, { "put", I_PUT, LOCAL }, { "pwd", I_PWD, REMOTE }, { "quit", I_QUIT, NOARGS }, { "reget", I_REGET, REMOTE }, { "rename", I_RENAME, REMOTE }, { "reput", I_REPUT, LOCAL }, { "rm", I_RM, REMOTE }, { "rmdir", I_RMDIR, REMOTE }, { "symlink", I_SYMLINK, REMOTE }, { "version", I_VERSION, NOARGS }, { "!", I_SHELL, NOARGS }, { "?", I_HELP, NOARGS }, { NULL, -1, -1 } }; int interactive_loop(struct sftp_conn *, char *file1, char *file2); /* ARGSUSED */ static void killchild(int signo) { if (sshpid > 1) { kill(sshpid, SIGTERM); waitpid(sshpid, NULL, 0); } _exit(1); } /* ARGSUSED */ static void cmd_interrupt(int signo) { const char msg[] = "\rInterrupt \n"; int olderrno = errno; (void)write(STDERR_FILENO, msg, sizeof(msg) - 1); interrupted = 1; errno = olderrno; } static void help(void) { printf("Available commands:\n" "bye Quit sftp\n" "cd path Change remote directory to 'path'\n" "chgrp grp path Change group of file 'path' to 'grp'\n" "chmod mode path Change permissions of file 'path' to 'mode'\n" "chown own path Change owner of file 'path' to 'own'\n" "df [-hi] [path] Display statistics for current directory or\n" " filesystem containing 'path'\n" "exit Quit sftp\n" "get [-afPpRr] remote [local] Download file\n" "reget [-fPpRr] remote [local] Resume download file\n" "reput [-fPpRr] [local] remote Resume upload file\n" "help Display this help text\n" "lcd path Change local directory to 'path'\n" "lls [ls-options [path]] Display local directory listing\n" "lmkdir path Create local directory\n" "ln [-s] oldpath newpath Link remote file (-s for symlink)\n" "lpwd Print local working directory\n" "ls [-1afhlnrSt] [path] Display remote directory listing\n" "lumask umask Set local umask to 'umask'\n" "mkdir path Create remote directory\n" "progress Toggle display of progress meter\n" "put [-afPpRr] local [remote] Upload file\n" "pwd Display remote working directory\n" "quit Quit sftp\n" "rename oldpath newpath Rename remote file\n" "rm path Delete remote file\n" "rmdir path Remove remote directory\n" "symlink oldpath newpath Symlink remote file\n" "version Show SFTP version\n" "!command Execute 'command' in local shell\n" "! Escape to local shell\n" "? Synonym for help\n"); } static void local_do_shell(const char *args) { int status; char *shell; pid_t pid; if (!*args) args = NULL; if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; if ((pid = fork()) == -1) fatal("Couldn't fork: %s", strerror(errno)); if (pid == 0) { /* XXX: child has pipe fds to ssh subproc open - issue? */ if (args) { debug3("Executing %s -c \"%s\"", shell, args); execl(shell, shell, "-c", args, (char *)NULL); } else { debug3("Executing %s", shell); execl(shell, shell, (char *)NULL); } fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell, strerror(errno)); _exit(1); } while (waitpid(pid, &status, 0) == -1) if (errno != EINTR) fatal("Couldn't wait for child: %s", strerror(errno)); if (!WIFEXITED(status)) error("Shell exited abnormally"); else if (WEXITSTATUS(status)) error("Shell exited with status %d", WEXITSTATUS(status)); } static void local_do_ls(const char *args) { if (!args || !*args) local_do_shell(_PATH_LS); else { int len = strlen(_PATH_LS " ") + strlen(args) + 1; char *buf = xmalloc(len); /* XXX: quoting - rip quoting code from ftp? */ snprintf(buf, len, _PATH_LS " %s", args); local_do_shell(buf); free(buf); } } /* Strip one path (usually the pwd) from the start of another */ static char * path_strip(char *path, char *strip) { size_t len; if (strip == NULL) return (xstrdup(path)); len = strlen(strip); if (strncmp(path, strip, len) == 0) { if (strip[len - 1] != '/' && path[len] == '/') len++; return (xstrdup(path + len)); } return (xstrdup(path)); } static char * make_absolute(char *p, char *pwd) { char *abs_str; /* Derelativise */ if (p && p[0] != '/') { abs_str = path_append(pwd, p); free(p); return(abs_str); } else return(p); } static int parse_getput_flags(const char *cmd, char **argv, int argc, int *aflag, int *fflag, int *pflag, int *rflag) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; *aflag = *fflag = *rflag = *pflag = 0; while ((ch = getopt(argc, argv, "afPpRr")) != -1) { switch (ch) { case 'a': *aflag = 1; break; case 'f': *fflag = 1; break; case 'p': case 'P': *pflag = 1; break; case 'r': case 'R': *rflag = 1; break; default: error("%s: Invalid flag -%c", cmd, optopt); return -1; } } return optind; } static int parse_link_flags(const char *cmd, char **argv, int argc, int *sflag) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; *sflag = 0; while ((ch = getopt(argc, argv, "s")) != -1) { switch (ch) { case 's': *sflag = 1; break; default: error("%s: Invalid flag -%c", cmd, optopt); return -1; } } return optind; } static int parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; *lflag = 0; while ((ch = getopt(argc, argv, "l")) != -1) { switch (ch) { case 'l': *lflag = 1; break; default: error("%s: Invalid flag -%c", cmd, optopt); return -1; } } return optind; } static int parse_ls_flags(char **argv, int argc, int *lflag) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; *lflag = LS_NAME_SORT; while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) { switch (ch) { case '1': *lflag &= ~VIEW_FLAGS; *lflag |= LS_SHORT_VIEW; break; case 'S': *lflag &= ~SORT_FLAGS; *lflag |= LS_SIZE_SORT; break; case 'a': *lflag |= LS_SHOW_ALL; break; case 'f': *lflag &= ~SORT_FLAGS; break; case 'h': *lflag |= LS_SI_UNITS; break; case 'l': *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_LONG_VIEW; break; case 'n': *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; break; case 'r': *lflag |= LS_REVERSE_SORT; break; case 't': *lflag &= ~SORT_FLAGS; *lflag |= LS_TIME_SORT; break; default: error("ls: Invalid flag -%c", optopt); return -1; } } return optind; } static int parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; *hflag = *iflag = 0; while ((ch = getopt(argc, argv, "hi")) != -1) { switch (ch) { case 'h': *hflag = 1; break; case 'i': *iflag = 1; break; default: error("%s: Invalid flag -%c", cmd, optopt); return -1; } } return optind; } static int parse_no_flags(const char *cmd, char **argv, int argc) { extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; opterr = 0; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { default: error("%s: Invalid flag -%c", cmd, optopt); return -1; } } return optind; } static int is_dir(char *path) { struct stat sb; /* XXX: report errors? */ if (stat(path, &sb) == -1) return(0); return(S_ISDIR(sb.st_mode)); } static int remote_is_dir(struct sftp_conn *conn, char *path) { Attrib *a; /* XXX: report errors? */ if ((a = do_stat(conn, path, 1)) == NULL) return(0); if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) return(0); return(S_ISDIR(a->perm)); } /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ static int pathname_is_dir(char *pathname) { size_t l = strlen(pathname); return l > 0 && pathname[l - 1] == '/'; } static int process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, int rflag, int resume, int fflag) { char *abs_src = NULL; char *abs_dst = NULL; glob_t g; char *filename, *tmp=NULL; int i, r, err = 0; abs_src = xstrdup(src); abs_src = make_absolute(abs_src, pwd); memset(&g, 0, sizeof(g)); debug3("Looking up %s", abs_src); if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) { if (r == GLOB_NOSPACE) { error("Too many matches for \"%s\".", abs_src); } else { error("File \"%s\" not found.", abs_src); } err = -1; goto out; } /* * If multiple matches then dst must be a directory or * unspecified. */ if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) { error("Multiple source paths, but destination " "\"%s\" is not a directory", dst); err = -1; goto out; } for (i = 0; g.gl_pathv[i] && !interrupted; i++) { tmp = xstrdup(g.gl_pathv[i]); if ((filename = basename(tmp)) == NULL) { error("basename %s: %s", tmp, strerror(errno)); free(tmp); err = -1; goto out; } if (g.gl_matchc == 1 && dst) { if (is_dir(dst)) { abs_dst = path_append(dst, filename); } else { abs_dst = xstrdup(dst); } } else if (dst) { abs_dst = path_append(dst, filename); } else { abs_dst = xstrdup(filename); } free(tmp); resume |= global_aflag; if (!quiet && resume) printf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); else if (!quiet && !resume) printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, pflag || global_pflag, 1, resume, fflag || global_fflag) == -1) err = -1; } else { if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, pflag || global_pflag, resume, fflag || global_fflag) == -1) err = -1; } free(abs_dst); abs_dst = NULL; } out: free(abs_src); globfree(&g); return(err); } static int process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, int rflag, int resume, int fflag) { char *tmp_dst = NULL; char *abs_dst = NULL; char *tmp = NULL, *filename = NULL; glob_t g; int err = 0; int i, dst_is_dir = 1; struct stat sb; if (dst) { tmp_dst = xstrdup(dst); tmp_dst = make_absolute(tmp_dst, pwd); } memset(&g, 0, sizeof(g)); debug3("Looking up %s", src); if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) { error("File \"%s\" not found.", src); err = -1; goto out; } /* If we aren't fetching to pwd then stash this status for later */ if (tmp_dst != NULL) dst_is_dir = remote_is_dir(conn, tmp_dst); /* If multiple matches, dst may be directory or unspecified */ if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) { error("Multiple paths match, but destination " "\"%s\" is not a directory", tmp_dst); err = -1; goto out; } for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (stat(g.gl_pathv[i], &sb) == -1) { err = -1; error("stat %s: %s", g.gl_pathv[i], strerror(errno)); continue; } tmp = xstrdup(g.gl_pathv[i]); if ((filename = basename(tmp)) == NULL) { error("basename %s: %s", tmp, strerror(errno)); free(tmp); err = -1; goto out; } if (g.gl_matchc == 1 && tmp_dst) { /* If directory specified, append filename */ if (dst_is_dir) abs_dst = path_append(tmp_dst, filename); else abs_dst = xstrdup(tmp_dst); } else if (tmp_dst) { abs_dst = path_append(tmp_dst, filename); } else { abs_dst = make_absolute(xstrdup(filename), pwd); } free(tmp); resume |= global_aflag; if (!quiet && resume) printf("Resuming upload of %s to %s\n", g.gl_pathv[i], abs_dst); else if (!quiet && !resume) printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { if (upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, fflag || global_fflag) == -1) err = -1; } else { if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, resume, fflag || global_fflag) == -1) err = -1; } } out: free(abs_dst); free(tmp_dst); globfree(&g); return(err); } static int sdirent_comp(const void *aa, const void *bb) { SFTP_DIRENT *a = *(SFTP_DIRENT **)aa; SFTP_DIRENT *b = *(SFTP_DIRENT **)bb; int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1; #define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1)) if (sort_flag & LS_NAME_SORT) return (rmul * strcmp(a->filename, b->filename)); else if (sort_flag & LS_TIME_SORT) return (rmul * NCMP(a->a.mtime, b->a.mtime)); else if (sort_flag & LS_SIZE_SORT) return (rmul * NCMP(a->a.size, b->a.size)); fatal("Unknown ls sort type"); } /* sftp ls.1 replacement for directories */ static int do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { int n; u_int c = 1, colspace = 0, columns = 1; SFTP_DIRENT **d; if ((n = do_readdir(conn, path, &d)) != 0) return (n); if (!(lflag & LS_SHORT_VIEW)) { u_int m = 0, width = 80; struct winsize ws; char *tmp; /* Count entries for sort and find longest filename */ for (n = 0; d[n] != NULL; n++) { if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL)) m = MAX(m, strlen(d[n]->filename)); } /* Add any subpath that also needs to be counted */ tmp = path_strip(path, strip_path); m += strlen(tmp); free(tmp); if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) width = ws.ws_col; columns = width / (m + 2); columns = MAX(columns, 1); colspace = width / columns; colspace = MIN(colspace, width); } if (lflag & SORT_FLAGS) { for (n = 0; d[n] != NULL; n++) ; /* count entries */ sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT); qsort(d, n, sizeof(*d), sdirent_comp); } for (n = 0; d[n] != NULL && !interrupted; n++) { char *tmp, *fname; if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL)) continue; tmp = path_append(path, d[n]->filename); fname = path_strip(tmp, strip_path); free(tmp); if (lflag & LS_LONG_VIEW) { if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) { char *lname; struct stat sb; memset(&sb, 0, sizeof(sb)); attrib_to_stat(&d[n]->a, &sb); lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS)); printf("%s\n", lname); free(lname); } else printf("%s\n", d[n]->longname); } else { printf("%-*s", colspace, fname); if (c >= columns) { printf("\n"); c = 1; } else c++; } free(fname); } if (!(lflag & LS_LONG_VIEW) && (c != 1)) printf("\n"); free_sftp_dirents(d); return (0); } /* sftp ls.1 replacement which handles path globs */ static int do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { char *fname, *lname; glob_t g; int err, r; struct winsize ws; u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80; memset(&g, 0, sizeof(g)); if ((r = remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT|GLOB_NOSORT, NULL, &g)) != 0 || (g.gl_pathc && !g.gl_matchc)) { if (g.gl_pathc) globfree(&g); if (r == GLOB_NOSPACE) { error("Can't ls: Too many matches for \"%s\"", path); } else { error("Can't ls: \"%s\" not found", path); } return -1; } if (interrupted) goto out; /* * If the glob returns a single match and it is a directory, * then just list its contents. */ if (g.gl_matchc == 1 && g.gl_statv[0] != NULL && S_ISDIR(g.gl_statv[0]->st_mode)) { err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); globfree(&g); return err; } if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) width = ws.ws_col; if (!(lflag & LS_SHORT_VIEW)) { /* Count entries for sort and find longest filename */ for (i = 0; g.gl_pathv[i]; i++) m = MAX(m, strlen(g.gl_pathv[i])); columns = width / (m + 2); columns = MAX(columns, 1); colspace = width / columns; } for (i = 0; g.gl_pathv[i] && !interrupted; i++) { fname = path_strip(g.gl_pathv[i], strip_path); if (lflag & LS_LONG_VIEW) { if (g.gl_statv[i] == NULL) { error("no stat information for %s", fname); continue; } lname = ls_file(fname, g.gl_statv[i], 1, (lflag & LS_SI_UNITS)); printf("%s\n", lname); free(lname); } else { printf("%-*s", colspace, fname); if (c >= columns) { printf("\n"); c = 1; } else c++; } free(fname); } if (!(lflag & LS_LONG_VIEW) && (c != 1)) printf("\n"); out: if (g.gl_pathc) globfree(&g); return 0; } static int do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) { struct sftp_statvfs st; char s_used[FMT_SCALED_STRSIZE]; char s_avail[FMT_SCALED_STRSIZE]; char s_root[FMT_SCALED_STRSIZE]; char s_total[FMT_SCALED_STRSIZE]; unsigned long long ffree; if (do_statvfs(conn, path, &st, 1) == -1) return -1; if (iflag) { ffree = st.f_files ? (100 * (st.f_files - st.f_ffree) / st.f_files) : 0; printf(" Inodes Used Avail " "(root) %%Capacity\n"); printf("%11llu %11llu %11llu %11llu %3llu%%\n", (unsigned long long)st.f_files, (unsigned long long)(st.f_files - st.f_ffree), (unsigned long long)st.f_favail, (unsigned long long)st.f_ffree, ffree); } else if (hflag) { strlcpy(s_used, "error", sizeof(s_used)); strlcpy(s_avail, "error", sizeof(s_avail)); strlcpy(s_root, "error", sizeof(s_root)); strlcpy(s_total, "error", sizeof(s_total)); fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used); fmt_scaled(st.f_bavail * st.f_frsize, s_avail); fmt_scaled(st.f_bfree * st.f_frsize, s_root); fmt_scaled(st.f_blocks * st.f_frsize, s_total); printf(" Size Used Avail (root) %%Capacity\n"); printf("%7sB %7sB %7sB %7sB %3llu%%\n", s_total, s_used, s_avail, s_root, (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / st.f_blocks)); } else { printf(" Size Used Avail " "(root) %%Capacity\n"); printf("%12llu %12llu %12llu %12llu %3llu%%\n", (unsigned long long)(st.f_frsize * st.f_blocks / 1024), (unsigned long long)(st.f_frsize * (st.f_blocks - st.f_bfree) / 1024), (unsigned long long)(st.f_frsize * st.f_bavail / 1024), (unsigned long long)(st.f_frsize * st.f_bfree / 1024), (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / st.f_blocks)); } return 0; } /* * Undo escaping of glob sequences in place. Used to undo extra escaping * applied in makeargv() when the string is destined for a function that * does not glob it. */ static void undo_glob_escape(char *s) { size_t i, j; for (i = j = 0;;) { if (s[i] == '\0') { s[j] = '\0'; return; } if (s[i] != '\\') { s[j++] = s[i++]; continue; } /* s[i] == '\\' */ ++i; switch (s[i]) { case '?': case '[': case '*': case '\\': s[j++] = s[i++]; break; case '\0': s[j++] = '\\'; s[j] = '\0'; return; default: s[j++] = '\\'; s[j++] = s[i++]; break; } } } /* * Split a string into an argument vector using sh(1)-style quoting, * comment and escaping rules, but with some tweaks to handle glob(3) * wildcards. * The "sloppy" flag allows for recovery from missing terminating quote, for * use in parsing incomplete commandlines during tab autocompletion. * * Returns NULL on error or a NULL-terminated array of arguments. * * If "lastquote" is not NULL, the quoting character used for the last * argument is placed in *lastquote ("\0", "'" or "\""). * * If "terminated" is not NULL, *terminated will be set to 1 when the * last argument's quote has been properly terminated or 0 otherwise. * This parameter is only of use if "sloppy" is set. */ #define MAXARGS 128 #define MAXARGLEN 8192 static char ** makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, u_int *terminated) { int argc, quot; size_t i, j; static char argvs[MAXARGLEN]; static char *argv[MAXARGS + 1]; enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q; *argcp = argc = 0; if (strlen(arg) > sizeof(argvs) - 1) { args_too_longs: error("string too long"); return NULL; } if (terminated != NULL) *terminated = 1; if (lastquote != NULL) *lastquote = '\0'; state = MA_START; i = j = 0; for (;;) { if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){ error("Too many arguments."); return NULL; } if (isspace((unsigned char)arg[i])) { if (state == MA_UNQUOTED) { /* Terminate current argument */ argvs[j++] = '\0'; argc++; state = MA_START; } else if (state != MA_START) argvs[j++] = arg[i]; } else if (arg[i] == '"' || arg[i] == '\'') { q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE; if (state == MA_START) { argv[argc] = argvs + j; state = q; if (lastquote != NULL) *lastquote = arg[i]; } else if (state == MA_UNQUOTED) state = q; else if (state == q) state = MA_UNQUOTED; else argvs[j++] = arg[i]; } else if (arg[i] == '\\') { if (state == MA_SQUOTE || state == MA_DQUOTE) { quot = state == MA_SQUOTE ? '\'' : '"'; /* Unescape quote we are in */ /* XXX support \n and friends? */ if (arg[i + 1] == quot) { i++; argvs[j++] = arg[i]; } else if (arg[i + 1] == '?' || arg[i + 1] == '[' || arg[i + 1] == '*') { /* * Special case for sftp: append * double-escaped glob sequence - * glob will undo one level of * escaping. NB. string can grow here. */ if (j >= sizeof(argvs) - 5) goto args_too_longs; argvs[j++] = '\\'; argvs[j++] = arg[i++]; argvs[j++] = '\\'; argvs[j++] = arg[i]; } else { argvs[j++] = arg[i++]; argvs[j++] = arg[i]; } } else { if (state == MA_START) { argv[argc] = argvs + j; state = MA_UNQUOTED; if (lastquote != NULL) *lastquote = '\0'; } if (arg[i + 1] == '?' || arg[i + 1] == '[' || arg[i + 1] == '*' || arg[i + 1] == '\\') { /* * Special case for sftp: append * escaped glob sequence - * glob will undo one level of * escaping. */ argvs[j++] = arg[i++]; argvs[j++] = arg[i]; } else { /* Unescape everything */ /* XXX support \n and friends? */ i++; argvs[j++] = arg[i]; } } } else if (arg[i] == '#') { if (state == MA_SQUOTE || state == MA_DQUOTE) argvs[j++] = arg[i]; else goto string_done; } else if (arg[i] == '\0') { if (state == MA_SQUOTE || state == MA_DQUOTE) { if (sloppy) { state = MA_UNQUOTED; if (terminated != NULL) *terminated = 0; goto string_done; } error("Unterminated quoted argument"); return NULL; } string_done: if (state == MA_UNQUOTED) { argvs[j++] = '\0'; argc++; } break; } else { if (state == MA_START) { argv[argc] = argvs + j; state = MA_UNQUOTED; if (lastquote != NULL) *lastquote = '\0'; } if ((state == MA_SQUOTE || state == MA_DQUOTE) && (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) { /* * Special case for sftp: escape quoted * glob(3) wildcards. NB. string can grow * here. */ if (j >= sizeof(argvs) - 3) goto args_too_longs; argvs[j++] = '\\'; argvs[j++] = arg[i]; } else argvs[j++] = arg[i]; } i++; } *argcp = argc; return argv; } static int parse_args(const char **cpp, int *ignore_errors, int *aflag, int *fflag, int *hflag, int *iflag, int *lflag, int *pflag, int *rflag, int *sflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; char *cp2, **argv; int base = 0; long l; int i, cmdnum, optidx, argc; /* Skip leading whitespace */ cp = cp + strspn(cp, WHITESPACE); /* Check for leading '-' (disable error processing) */ *ignore_errors = 0; if (*cp == '-') { *ignore_errors = 1; cp++; cp = cp + strspn(cp, WHITESPACE); } /* Ignore blank lines and lines which begin with comment '#' char */ if (*cp == '\0' || *cp == '#') return (0); if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL) return -1; /* Figure out which command we have */ for (i = 0; cmds[i].c != NULL; i++) { if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0) break; } cmdnum = cmds[i].n; cmd = cmds[i].c; /* Special case */ if (*cp == '!') { cp++; cmdnum = I_SHELL; } else if (cmdnum == -1) { error("Invalid command."); return -1; } /* Get arguments and parse flags */ *aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0; *rflag = *sflag = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { case I_GET: case I_REGET: case I_REPUT: case I_PUT: if ((optidx = parse_getput_flags(cmd, argv, argc, aflag, fflag, pflag, rflag)) == -1) return -1; /* Get first pathname (mandatory) */ if (argc - optidx < 1) { error("You must specify at least one path after a " "%s command.", cmd); return -1; } *path1 = xstrdup(argv[optidx]); /* Get second pathname (optional) */ if (argc - optidx > 1) { *path2 = xstrdup(argv[optidx + 1]); /* Destination is not globbed */ undo_glob_escape(*path2); } break; case I_LINK: if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) return -1; goto parse_two_paths; case I_RENAME: if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1) return -1; goto parse_two_paths; case I_SYMLINK: if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) return -1; parse_two_paths: if (argc - optidx < 2) { error("You must specify two paths after a %s " "command.", cmd); return -1; } *path1 = xstrdup(argv[optidx]); *path2 = xstrdup(argv[optidx + 1]); /* Paths are not globbed */ undo_glob_escape(*path1); undo_glob_escape(*path2); break; case I_RM: case I_MKDIR: case I_RMDIR: case I_CHDIR: case I_LCHDIR: case I_LMKDIR: if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) return -1; /* Get pathname (mandatory) */ if (argc - optidx < 1) { error("You must specify a path after a %s command.", cmd); return -1; } *path1 = xstrdup(argv[optidx]); /* Only "rm" globs */ if (cmdnum != I_RM) undo_glob_escape(*path1); break; case I_DF: if ((optidx = parse_df_flags(cmd, argv, argc, hflag, iflag)) == -1) return -1; /* Default to current directory if no path specified */ if (argc - optidx < 1) *path1 = NULL; else { *path1 = xstrdup(argv[optidx]); undo_glob_escape(*path1); } break; case I_LS: if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1) return(-1); /* Path is optional */ if (argc - optidx > 0) *path1 = xstrdup(argv[optidx]); break; case I_LLS: /* Skip ls command and following whitespace */ cp = cp + strlen(cmd) + strspn(cp, WHITESPACE); case I_SHELL: /* Uses the rest of the line */ break; case I_LUMASK: case I_CHMOD: base = 8; case I_CHOWN: case I_CHGRP: if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) return -1; /* Get numeric arg (mandatory) */ if (argc - optidx < 1) goto need_num_arg; errno = 0; l = strtol(argv[optidx], &cp2, base); if (cp2 == argv[optidx] || *cp2 != '\0' || ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) || l < 0) { need_num_arg: error("You must supply a numeric argument " "to the %s command.", cmd); return -1; } *n_arg = l; if (cmdnum == I_LUMASK) break; /* Get pathname (mandatory) */ if (argc - optidx < 2) { error("You must specify a path after a %s command.", cmd); return -1; } *path1 = xstrdup(argv[optidx + 1]); break; case I_QUIT: case I_PWD: case I_LPWD: case I_HELP: case I_VERSION: case I_PROGRESS: if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) return -1; break; default: fatal("Command not implemented"); } *cpp = cp; return(cmdnum); } static int parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, iflag = 0; int lflag = 0, pflag = 0, rflag = 0, sflag = 0; int cmdnum, i; unsigned long n_arg = 0; Attrib a, *aa; char path_buf[PATH_MAX]; int err = 0; glob_t g; path1 = path2 = NULL; cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); if (ignore_errors != 0) err_abort = 0; memset(&g, 0, sizeof(g)); /* Perform command */ switch (cmdnum) { case 0: /* Blank line */ break; case -1: /* Unrecognized command */ err = -1; break; case I_REGET: aflag = 1; /* FALLTHROUGH */ case I_GET: err = process_get(conn, path1, path2, *pwd, pflag, rflag, aflag, fflag); break; case I_REPUT: aflag = 1; /* FALLTHROUGH */ case I_PUT: err = process_put(conn, path1, path2, *pwd, pflag, rflag, aflag, fflag); break; case I_RENAME: path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); err = do_rename(conn, path1, path2, lflag); break; case I_SYMLINK: sflag = 1; case I_LINK: if (!sflag) path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2); break; case I_RM: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!quiet) printf("Removing %s\n", g.gl_pathv[i]); err = do_rm(conn, g.gl_pathv[i]); if (err != 0 && err_abort) break; } break; case I_MKDIR: path1 = make_absolute(path1, *pwd); attrib_clear(&a); a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = 0777; err = do_mkdir(conn, path1, &a, 1); break; case I_RMDIR: path1 = make_absolute(path1, *pwd); err = do_rmdir(conn, path1); break; case I_CHDIR: path1 = make_absolute(path1, *pwd); if ((tmp = do_realpath(conn, path1)) == NULL) { err = 1; break; } if ((aa = do_stat(conn, tmp, 0)) == NULL) { free(tmp); err = 1; break; } if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { error("Can't change directory: Can't check target"); free(tmp); err = 1; break; } if (!S_ISDIR(aa->perm)) { error("Can't change directory: \"%s\" is not " "a directory", tmp); free(tmp); err = 1; break; } free(*pwd); *pwd = tmp; break; case I_LS: if (!path1) { do_ls_dir(conn, *pwd, *pwd, lflag); break; } /* Strip pwd off beginning of non-absolute paths */ tmp = NULL; if (*path1 != '/') tmp = *pwd; path1 = make_absolute(path1, *pwd); err = do_globbed_ls(conn, path1, tmp, lflag); break; case I_DF: /* Default to current directory if no path specified */ if (path1 == NULL) path1 = xstrdup(*pwd); path1 = make_absolute(path1, *pwd); err = do_df(conn, path1, hflag, iflag); break; case I_LCHDIR: tmp = tilde_expand_filename(path1, getuid()); free(path1); path1 = tmp; if (chdir(path1) == -1) { error("Couldn't change local directory to " "\"%s\": %s", path1, strerror(errno)); err = 1; } break; case I_LMKDIR: if (mkdir(path1, 0777) == -1) { error("Couldn't create local directory " "\"%s\": %s", path1, strerror(errno)); err = 1; } break; case I_LLS: local_do_ls(cmd); break; case I_SHELL: local_do_shell(cmd); break; case I_LUMASK: umask(n_arg); printf("Local umask: %03lo\n", n_arg); break; case I_CHMOD: path1 = make_absolute(path1, *pwd); attrib_clear(&a); a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = n_arg; remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!quiet) printf("Changing mode on %s\n", g.gl_pathv[i]); err = do_setstat(conn, g.gl_pathv[i], &a); if (err != 0 && err_abort) break; } break; case I_CHOWN: case I_CHGRP: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { if (err_abort) { err = -1; break; } else continue; } if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { error("Can't get current ownership of " "remote file \"%s\"", g.gl_pathv[i]); if (err_abort) { err = -1; break; } else continue; } aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; if (cmdnum == I_CHOWN) { if (!quiet) printf("Changing owner on %s\n", g.gl_pathv[i]); aa->uid = n_arg; } else { if (!quiet) printf("Changing group on %s\n", g.gl_pathv[i]); aa->gid = n_arg; } err = do_setstat(conn, g.gl_pathv[i], aa); if (err != 0 && err_abort) break; } break; case I_PWD: printf("Remote working directory: %s\n", *pwd); break; case I_LPWD: if (!getcwd(path_buf, sizeof(path_buf))) { error("Couldn't get local cwd: %s", strerror(errno)); err = -1; break; } printf("Local working directory: %s\n", path_buf); break; case I_QUIT: /* Processed below */ break; case I_HELP: help(); break; case I_VERSION: printf("SFTP protocol version %u\n", sftp_proto_version(conn)); break; case I_PROGRESS: showprogress = !showprogress; if (showprogress) printf("Progress meter enabled\n"); else printf("Progress meter disabled\n"); break; default: fatal("%d is not implemented", cmdnum); } if (g.gl_pathc) globfree(&g); free(path1); free(path2); /* If an unignored error occurs in batch mode we should abort. */ if (err_abort && err != 0) return (-1); else if (cmdnum == I_QUIT) return (1); return (0); } #ifdef USE_LIBEDIT static char * prompt(EditLine *el) { return ("sftp> "); } /* Display entries in 'list' after skipping the first 'len' chars */ static void complete_display(char **list, u_int len) { u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen; struct winsize ws; char *tmp; /* Count entries for sort and find longest */ for (y = 0; list[y]; y++) m = MAX(m, strlen(list[y])); if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) width = ws.ws_col; m = m > len ? m - len : 0; columns = width / (m + 2); columns = MAX(columns, 1); colspace = width / columns; colspace = MIN(colspace, width); printf("\n"); m = 1; for (y = 0; list[y]; y++) { llen = strlen(list[y]); tmp = llen > len ? list[y] + len : ""; printf("%-*s", colspace, tmp); if (m >= columns) { printf("\n"); m = 1; } else m++; } printf("\n"); } /* * Given a "list" of words that begin with a common prefix of "word", * attempt to find an autocompletion to extends "word" by the next * characters common to all entries in "list". */ static char * complete_ambiguous(const char *word, char **list, size_t count) { if (word == NULL) return NULL; if (count > 0) { u_int y, matchlen = strlen(list[0]); /* Find length of common stem */ for (y = 1; list[y]; y++) { u_int x; for (x = 0; x < matchlen; x++) if (list[0][x] != list[y][x]) break; matchlen = x; } if (matchlen > strlen(word)) { char *tmp = xstrdup(list[0]); tmp[matchlen] = '\0'; return tmp; } } return xstrdup(word); } /* Autocomplete a sftp command */ static int complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote, int terminated) { u_int y, count = 0, cmdlen, tmplen; char *tmp, **list, argterm[3]; const LineInfo *lf; list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *)); /* No command specified: display all available commands */ if (cmd == NULL) { for (y = 0; cmds[y].c; y++) list[count++] = xstrdup(cmds[y].c); list[count] = NULL; complete_display(list, 0); for (y = 0; list[y] != NULL; y++) free(list[y]); free(list); return count; } /* Prepare subset of commands that start with "cmd" */ cmdlen = strlen(cmd); for (y = 0; cmds[y].c; y++) { if (!strncasecmp(cmd, cmds[y].c, cmdlen)) list[count++] = xstrdup(cmds[y].c); } list[count] = NULL; if (count == 0) { free(list); return 0; } /* Complete ambigious command */ tmp = complete_ambiguous(cmd, list, count); if (count > 1) complete_display(list, 0); for (y = 0; list[y]; y++) free(list[y]); free(list); if (tmp != NULL) { tmplen = strlen(tmp); cmdlen = strlen(cmd); /* If cmd may be extended then do so */ if (tmplen > cmdlen) if (el_insertstr(el, tmp + cmdlen) == -1) fatal("el_insertstr failed."); lf = el_line(el); /* Terminate argument cleanly */ if (count == 1) { y = 0; if (!terminated) argterm[y++] = quote; if (lastarg || *(lf->cursor) != ' ') argterm[y++] = ' '; argterm[y] = '\0'; if (y > 0 && el_insertstr(el, argterm) == -1) fatal("el_insertstr failed."); } free(tmp); } return count; } /* * Determine whether a particular sftp command's arguments (if any) * represent local or remote files. */ static int complete_is_remote(char *cmd) { int i; if (cmd == NULL) return -1; for (i = 0; cmds[i].c; i++) { if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) return cmds[i].t; } return -1; } /* Autocomplete a filename "file" */ static int complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, char *file, int remote, int lastarg, char quote, int terminated) { glob_t g; char *tmp, *tmp2, ins[8]; u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; int clen; const LineInfo *lf; /* Glob from "file" location */ if (file == NULL) tmp = xstrdup("*"); else xasprintf(&tmp, "%s*", file); /* Check if the path is absolute. */ isabs = tmp[0] == '/'; memset(&g, 0, sizeof(g)); if (remote != LOCAL) { tmp = make_absolute(tmp, remote_path); remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); } else glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); /* Determine length of pwd so we can trim completion display */ for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { /* Terminate counting on first unescaped glob metacharacter */ if (tmp[tmplen] == '*' || tmp[tmplen] == '?') { if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0') hadglob = 1; break; } if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0') tmplen++; if (tmp[tmplen] == '/') pwdlen = tmplen + 1; /* track last seen '/' */ } free(tmp); tmp = NULL; if (g.gl_matchc == 0) goto out; if (g.gl_matchc > 1) complete_display(g.gl_pathv, pwdlen); /* Don't try to extend globs */ if (file == NULL || hadglob) goto out; tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc); tmp = path_strip(tmp2, isabs ? NULL : remote_path); free(tmp2); if (tmp == NULL) goto out; tmplen = strlen(tmp); filelen = strlen(file); /* Count the number of escaped characters in the input string. */ cesc = isesc = 0; for (i = 0; i < filelen; i++) { if (!isesc && file[i] == '\\' && i + 1 < filelen){ isesc = 1; cesc++; } else isesc = 0; } if (tmplen > (filelen - cesc)) { tmp2 = tmp + filelen - cesc; len = strlen(tmp2); /* quote argument on way out */ for (i = 0; i < len; i += clen) { if ((clen = mblen(tmp2 + i, len - i)) < 0 || (size_t)clen > sizeof(ins) - 2) fatal("invalid multibyte character"); ins[0] = '\\'; memcpy(ins + 1, tmp2 + i, clen); ins[clen + 1] = '\0'; switch (tmp2[i]) { case '\'': case '"': case '\\': case '\t': case '[': case ' ': case '#': case '*': if (quote == '\0' || tmp2[i] == quote) { if (el_insertstr(el, ins) == -1) fatal("el_insertstr " "failed."); break; } /* FALLTHROUGH */ default: if (el_insertstr(el, ins + 1) == -1) fatal("el_insertstr failed."); break; } } } lf = el_line(el); if (g.gl_matchc == 1) { i = 0; if (!terminated && quote != '\0') ins[i++] = quote; if (*(lf->cursor - 1) != '/' && (lastarg || *(lf->cursor) != ' ')) ins[i++] = ' '; ins[i] = '\0'; if (i > 0 && el_insertstr(el, ins) == -1) fatal("el_insertstr failed."); } free(tmp); out: globfree(&g); return g.gl_matchc; } /* tab-completion hook function, called via libedit */ static unsigned char complete(EditLine *el, int ch) { char **argv, *line, quote; int argc, carg; u_int cursor, len, terminated, ret = CC_ERROR; const LineInfo *lf; struct complete_ctx *complete_ctx; lf = el_line(el); if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0) fatal("%s: el_get failed", __func__); /* Figure out which argument the cursor points to */ cursor = lf->cursor - lf->buffer; line = xmalloc(cursor + 1); memcpy(line, lf->buffer, cursor); line[cursor] = '\0'; argv = makeargv(line, &carg, 1, "e, &terminated); free(line); /* Get all the arguments on the line */ len = lf->lastchar - lf->buffer; line = xmalloc(len + 1); memcpy(line, lf->buffer, len); line[len] = '\0'; argv = makeargv(line, &argc, 1, NULL, NULL); /* Ensure cursor is at EOL or a argument boundary */ if (line[cursor] != ' ' && line[cursor] != '\0' && line[cursor] != '\n') { free(line); return ret; } if (carg == 0) { /* Show all available commands */ complete_cmd_parse(el, NULL, argc == carg, '\0', 1); ret = CC_REDISPLAY; } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { /* Handle the command parsing */ if (complete_cmd_parse(el, argv[0], argc == carg, quote, terminated) != 0) ret = CC_REDISPLAY; } else if (carg >= 1) { /* Handle file parsing */ int remote = complete_is_remote(argv[0]); char *filematch = NULL; if (carg > 1 && line[cursor-1] != ' ') filematch = argv[carg - 1]; if (remote != 0 && complete_match(el, complete_ctx->conn, *complete_ctx->remote_pathp, filematch, remote, carg == argc, quote, terminated) != 0) ret = CC_REDISPLAY; } free(line); return ret; } #endif /* USE_LIBEDIT */ int interactive_loop(struct sftp_conn *conn, char *file1, char *file2) { char *remote_path; char *dir = NULL; char cmd[2048]; int err, interactive; EditLine *el = NULL; #ifdef USE_LIBEDIT History *hl = NULL; HistEvent hev; extern char *__progname; struct complete_ctx complete_ctx; if (!batchmode && isatty(STDIN_FILENO)) { if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL) fatal("Couldn't initialise editline"); if ((hl = history_init()) == NULL) fatal("Couldn't initialise editline history"); history(hl, &hev, H_SETSIZE, 100); el_set(el, EL_HIST, history, hl); el_set(el, EL_PROMPT, prompt); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_TERMINAL, NULL); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); /* Tab Completion */ el_set(el, EL_ADDFN, "ftp-complete", "Context sensitive argument completion", complete); complete_ctx.conn = conn; complete_ctx.remote_pathp = &remote_path; el_set(el, EL_CLIENTDATA, (void*)&complete_ctx); el_set(el, EL_BIND, "^I", "ftp-complete", NULL); /* enable ctrl-left-arrow and ctrl-right-arrow */ el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL); el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL); el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); /* make ^w match ksh behaviour */ el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL); } #endif /* USE_LIBEDIT */ remote_path = do_realpath(conn, "."); if (remote_path == NULL) fatal("Need cwd"); if (file1 != NULL) { dir = xstrdup(file1); dir = make_absolute(dir, remote_path); if (remote_is_dir(conn, dir) && file2 == NULL) { if (!quiet) printf("Changing to: %s\n", dir); snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); if (parse_dispatch_command(conn, cmd, &remote_path, 1) != 0) { free(dir); free(remote_path); free(conn); return (-1); } } else { /* XXX this is wrong wrt quoting */ snprintf(cmd, sizeof cmd, "get%s %s%s%s", global_aflag ? " -a" : "", dir, file2 == NULL ? "" : " ", file2 == NULL ? "" : file2); err = parse_dispatch_command(conn, cmd, &remote_path, 1); free(dir); free(remote_path); free(conn); return (err); } free(dir); } setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(infile, NULL, _IOLBF, 0); interactive = !batchmode && isatty(STDIN_FILENO); err = 0; for (;;) { char *cp; signal(SIGINT, SIG_IGN); if (el == NULL) { if (interactive) printf("sftp> "); if (fgets(cmd, sizeof(cmd), infile) == NULL) { if (interactive) printf("\n"); break; } if (!interactive) { /* Echo command */ printf("sftp> %s", cmd); if (strlen(cmd) > 0 && cmd[strlen(cmd) - 1] != '\n') printf("\n"); } } else { #ifdef USE_LIBEDIT const char *line; int count = 0; if ((line = el_gets(el, &count)) == NULL || count <= 0) { printf("\n"); break; } history(hl, &hev, H_ENTER, line); if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) { fprintf(stderr, "Error: input line too long\n"); continue; } #endif /* USE_LIBEDIT */ } cp = strrchr(cmd, '\n'); if (cp) *cp = '\0'; /* Handle user interrupts gracefully during commands */ interrupted = 0; signal(SIGINT, cmd_interrupt); err = parse_dispatch_command(conn, cmd, &remote_path, batchmode); if (err != 0) break; } free(remote_path); free(conn); #ifdef USE_LIBEDIT if (el != NULL) el_end(el); #endif /* USE_LIBEDIT */ /* err == 1 signifies normal "quit" exit */ return (err >= 0 ? 0 : -1); } static void connect_to_server(char *path, char **args, int *in, int *out) { int c_in, c_out; #ifdef USE_PIPES int pin[2], pout[2]; if ((pipe(pin) == -1) || (pipe(pout) == -1)) fatal("pipe: %s", strerror(errno)); *in = pin[0]; *out = pout[1]; c_in = pout[0]; c_out = pin[1]; #else /* USE_PIPES */ int inout[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) fatal("socketpair: %s", strerror(errno)); *in = *out = inout[0]; c_in = c_out = inout[1]; #endif /* USE_PIPES */ if ((sshpid = fork()) == -1) fatal("fork: %s", strerror(errno)); else if (sshpid == 0) { if ((dup2(c_in, STDIN_FILENO) == -1) || (dup2(c_out, STDOUT_FILENO) == -1)) { fprintf(stderr, "dup2: %s\n", strerror(errno)); _exit(1); } close(*in); close(*out); close(c_in); close(c_out); /* * The underlying ssh is in the same process group, so we must * ignore SIGINT if we want to gracefully abort commands, * otherwise the signal will make it to the ssh process and * kill it too. Contrawise, since sftp sends SIGTERMs to the * underlying ssh, it must *not* ignore that signal. */ signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_DFL); execvp(path, args); fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); _exit(1); } signal(SIGTERM, killchild); signal(SIGINT, killchild); signal(SIGHUP, killchild); close(c_in); close(c_out); } static void usage(void) { extern char *__progname; fprintf(stderr, "usage: %s [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" " [-D sftp_server_path] [-F ssh_config] " "[-i identity_file] [-l limit]\n" " [-o ssh_option] [-P port] [-R num_requests] " "[-S program]\n" " [-s subsystem | sftp_server] host\n" " %s [user@]host[:file ...]\n" " %s [user@]host[:dir[/]]\n" " %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname); exit(1); } int main(int argc, char **argv) { int in, out, ch, err; char *host = NULL, *userhost, *cp, *file2 = NULL; int debug_level = 0, sshver = 2; char *file1 = NULL, *sftp_server = NULL; char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; const char *errstr; LogLevel ll = SYSLOG_LEVEL_INFO; arglist args; extern int optind; extern char *optarg; struct sftp_conn *conn; size_t copy_buffer_len = DEFAULT_COPY_BUFLEN; size_t num_requests = DEFAULT_NUM_REQUESTS; long long limit_kbps = 0; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); setlocale(LC_CTYPE, ""); __progname = ssh_get_progname(argv[0]); memset(&args, '\0', sizeof(args)); args.list = NULL; addargs(&args, "%s", ssh_program); addargs(&args, "-oForwardX11 no"); addargs(&args, "-oForwardAgent no"); addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); ll = SYSLOG_LEVEL_INFO; infile = stdin; while ((ch = getopt(argc, argv, "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': case '6': case 'C': addargs(&args, "-%c", ch); break; /* Passed through to ssh(1) with argument */ case 'F': case 'c': case 'i': case 'o': addargs(&args, "-%c", ch); addargs(&args, "%s", optarg); break; case 'q': ll = SYSLOG_LEVEL_ERROR; quiet = 1; showprogress = 0; addargs(&args, "-%c", ch); break; case 'P': addargs(&args, "-oPort %s", optarg); break; case 'v': if (debug_level < 3) { addargs(&args, "-v"); ll = SYSLOG_LEVEL_DEBUG1 + debug_level; } debug_level++; break; case '1': sshver = 1; if (sftp_server == NULL) sftp_server = _PATH_SFTP_SERVER; break; case '2': sshver = 2; break; case 'a': global_aflag = 1; break; case 'B': copy_buffer_len = strtol(optarg, &cp, 10); if (copy_buffer_len == 0 || *cp != '\0') fatal("Invalid buffer size \"%s\"", optarg); break; case 'b': if (batchmode) fatal("Batch file already specified."); /* Allow "-" as stdin */ if (strcmp(optarg, "-") != 0 && (infile = fopen(optarg, "r")) == NULL) fatal("%s (%s).", strerror(errno), optarg); showprogress = 0; quiet = batchmode = 1; addargs(&args, "-obatchmode yes"); break; case 'f': global_fflag = 1; break; case 'p': global_pflag = 1; break; case 'D': sftp_direct = optarg; break; case 'l': limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, &errstr); if (errstr != NULL) usage(); limit_kbps *= 1024; /* kbps */ break; case 'r': global_rflag = 1; break; case 'R': num_requests = strtol(optarg, &cp, 10); if (num_requests == 0 || *cp != '\0') fatal("Invalid number of requests \"%s\"", optarg); break; case 's': sftp_server = optarg; break; case 'S': ssh_program = optarg; replacearg(&args, 0, "%s", ssh_program); break; case 'h': default: usage(); } } if (!isatty(STDERR_FILENO)) showprogress = 0; log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); if (sftp_direct == NULL) { if (optind == argc || argc > (optind + 2)) usage(); userhost = xstrdup(argv[optind]); file2 = argv[optind+1]; if ((host = strrchr(userhost, '@')) == NULL) host = userhost; else { *host++ = '\0'; if (!userhost[0]) { fprintf(stderr, "Missing username\n"); usage(); } addargs(&args, "-l"); addargs(&args, "%s", userhost); } if ((cp = colon(host)) != NULL) { *cp++ = '\0'; file1 = cp; } host = cleanhostname(host); if (!*host) { fprintf(stderr, "Missing hostname\n"); usage(); } addargs(&args, "-oProtocol %d", sshver); /* no subsystem if the server-spec contains a '/' */ if (sftp_server == NULL || strchr(sftp_server, '/') == NULL) addargs(&args, "-s"); addargs(&args, "--"); addargs(&args, "%s", host); addargs(&args, "%s", (sftp_server != NULL ? sftp_server : "sftp")); connect_to_server(ssh_program, args.list, &in, &out); } else { args.list = NULL; addargs(&args, "sftp-server"); connect_to_server(sftp_direct, args.list, &in, &out); } freeargs(&args); conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps); if (conn == NULL) fatal("Couldn't initialise connection to server"); if (!quiet) { if (sftp_direct == NULL) fprintf(stderr, "Connected to %s.\n", host); else fprintf(stderr, "Attached to %s.\n", sftp_direct); } err = interactive_loop(conn, file1, file2); #if !defined(USE_PIPES) shutdown(in, SHUT_RDWR); shutdown(out, SHUT_RDWR); #endif close(in); close(out); if (batchmode) fclose(infile); while (waitpid(sshpid, NULL, 0) == -1) if (errno != EINTR) fatal("Couldn't wait for ssh process: %s", strerror(errno)); exit(err == 0 ? 0 : 1); } openssh-7.2p2/sftp.h010064400017500001750000000065221267006270000126040ustar00djmdjm/* $OpenBSD: sftp.h,v 1.9 2008/06/13 00:12:02 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. */ /* * draft-ietf-secsh-filexfer-01.txt */ /* version */ #define SSH2_FILEXFER_VERSION 3 /* client to server */ #define SSH2_FXP_INIT 1 #define SSH2_FXP_OPEN 3 #define SSH2_FXP_CLOSE 4 #define SSH2_FXP_READ 5 #define SSH2_FXP_WRITE 6 #define SSH2_FXP_LSTAT 7 #define SSH2_FXP_STAT_VERSION_0 7 #define SSH2_FXP_FSTAT 8 #define SSH2_FXP_SETSTAT 9 #define SSH2_FXP_FSETSTAT 10 #define SSH2_FXP_OPENDIR 11 #define SSH2_FXP_READDIR 12 #define SSH2_FXP_REMOVE 13 #define SSH2_FXP_MKDIR 14 #define SSH2_FXP_RMDIR 15 #define SSH2_FXP_REALPATH 16 #define SSH2_FXP_STAT 17 #define SSH2_FXP_RENAME 18 #define SSH2_FXP_READLINK 19 #define SSH2_FXP_SYMLINK 20 /* server to client */ #define SSH2_FXP_VERSION 2 #define SSH2_FXP_STATUS 101 #define SSH2_FXP_HANDLE 102 #define SSH2_FXP_DATA 103 #define SSH2_FXP_NAME 104 #define SSH2_FXP_ATTRS 105 #define SSH2_FXP_EXTENDED 200 #define SSH2_FXP_EXTENDED_REPLY 201 /* attributes */ #define SSH2_FILEXFER_ATTR_SIZE 0x00000001 #define SSH2_FILEXFER_ATTR_UIDGID 0x00000002 #define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004 #define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008 #define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000 /* portable open modes */ #define SSH2_FXF_READ 0x00000001 #define SSH2_FXF_WRITE 0x00000002 #define SSH2_FXF_APPEND 0x00000004 #define SSH2_FXF_CREAT 0x00000008 #define SSH2_FXF_TRUNC 0x00000010 #define SSH2_FXF_EXCL 0x00000020 /* statvfs@openssh.com f_flag flags */ #define SSH2_FXE_STATVFS_ST_RDONLY 0x00000001 #define SSH2_FXE_STATVFS_ST_NOSUID 0x00000002 /* status messages */ #define SSH2_FX_OK 0 #define SSH2_FX_EOF 1 #define SSH2_FX_NO_SUCH_FILE 2 #define SSH2_FX_PERMISSION_DENIED 3 #define SSH2_FX_FAILURE 4 #define SSH2_FX_BAD_MESSAGE 5 #define SSH2_FX_NO_CONNECTION 6 #define SSH2_FX_CONNECTION_LOST 7 #define SSH2_FX_OP_UNSUPPORTED 8 #define SSH2_FX_MAX 8 struct passwd; int sftp_server_main(int, char **, struct passwd *); void sftp_server_cleanup_exit(int) __attribute__((noreturn)); openssh-7.2p2/smult_curve25519_ref.c010064400017500001750000000153241267006270000154350ustar00djmdjm/* $OpenBSD: smult_curve25519_ref.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */ /* version 20081011 Matthew Dempsky Public domain. Derived from public domain code by D. J. Bernstein. */ int crypto_scalarmult_curve25519(unsigned char *, const unsigned char *, const unsigned char *); static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) { unsigned int j; unsigned int u; u = 0; for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } u += a[31] + b[31]; out[31] = u; } static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) { unsigned int j; unsigned int u; u = 218; for (j = 0;j < 31;++j) { u += a[j] + 65280 - b[j]; out[j] = u & 255; u >>= 8; } u += a[31] - b[31]; out[31] = u; } static void squeeze(unsigned int a[32]) { unsigned int j; unsigned int u; u = 0; for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } u += a[31]; a[31] = u & 127; u = 19 * (u >> 7); for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } u += a[31]; a[31] = u; } static const unsigned int minusp[32] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 } ; static void freeze(unsigned int a[32]) { unsigned int aorig[32]; unsigned int j; unsigned int negative; for (j = 0;j < 32;++j) aorig[j] = a[j]; add(a,a,minusp); negative = -((a[31] >> 7) & 1); for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); } static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) { unsigned int i; unsigned int j; unsigned int u; for (i = 0;i < 32;++i) { u = 0; for (j = 0;j <= i;++j) u += a[j] * b[i - j]; for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; out[i] = u; } squeeze(out); } static void mult121665(unsigned int out[32],const unsigned int a[32]) { unsigned int j; unsigned int u; u = 0; for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } u += 121665 * a[31]; out[31] = u & 127; u = 19 * (u >> 7); for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } u += out[j]; out[j] = u; } static void square(unsigned int out[32],const unsigned int a[32]) { unsigned int i; unsigned int j; unsigned int u; for (i = 0;i < 32;++i) { u = 0; for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; u *= 2; if ((i & 1) == 0) { u += a[i / 2] * a[i / 2]; u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; } out[i] = u; } squeeze(out); } static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) { unsigned int j; unsigned int t; unsigned int bminus1; bminus1 = b - 1; for (j = 0;j < 64;++j) { t = bminus1 & (r[j] ^ s[j]); p[j] = s[j] ^ t; q[j] = r[j] ^ t; } } static void mainloop(unsigned int work[64],const unsigned char e[32]) { unsigned int xzm1[64]; unsigned int xzm[64]; unsigned int xzmb[64]; unsigned int xzm1b[64]; unsigned int xznb[64]; unsigned int xzn1b[64]; unsigned int a0[64]; unsigned int a1[64]; unsigned int b0[64]; unsigned int b1[64]; unsigned int c1[64]; unsigned int r[32]; unsigned int s[32]; unsigned int t[32]; unsigned int u[32]; unsigned int j; unsigned int b; int pos; for (j = 0;j < 32;++j) xzm1[j] = work[j]; xzm1[32] = 1; for (j = 33;j < 64;++j) xzm1[j] = 0; xzm[0] = 1; for (j = 1;j < 64;++j) xzm[j] = 0; for (pos = 254;pos >= 0;--pos) { b = e[pos / 8] >> (pos & 7); b &= 1; select(xzmb,xzm1b,xzm,xzm1,b); add(a0,xzmb,xzmb + 32); sub(a0 + 32,xzmb,xzmb + 32); add(a1,xzm1b,xzm1b + 32); sub(a1 + 32,xzm1b,xzm1b + 32); square(b0,a0); square(b0 + 32,a0 + 32); mult(b1,a1,a0 + 32); mult(b1 + 32,a1 + 32,a0); add(c1,b1,b1 + 32); sub(c1 + 32,b1,b1 + 32); square(r,c1 + 32); sub(s,b0,b0 + 32); mult121665(t,s); add(u,t,b0); mult(xznb,b0,b0 + 32); mult(xznb + 32,s,u); square(xzn1b,c1); mult(xzn1b + 32,r,work); select(xzm,xzm1,xznb,xzn1b,b); } for (j = 0;j < 64;++j) work[j] = xzm[j]; } static void recip(unsigned int out[32],const unsigned int z[32]) { unsigned int z2[32]; unsigned int z9[32]; unsigned int z11[32]; unsigned int z2_5_0[32]; unsigned int z2_10_0[32]; unsigned int z2_20_0[32]; unsigned int z2_50_0[32]; unsigned int z2_100_0[32]; unsigned int t0[32]; unsigned int t1[32]; int i; /* 2 */ square(z2,z); /* 4 */ square(t1,z2); /* 8 */ square(t0,t1); /* 9 */ mult(z9,t0,z); /* 11 */ mult(z11,z9,z2); /* 22 */ square(t0,z11); /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); /* 2^6 - 2^1 */ square(t0,z2_5_0); /* 2^7 - 2^2 */ square(t1,t0); /* 2^8 - 2^3 */ square(t0,t1); /* 2^9 - 2^4 */ square(t1,t0); /* 2^10 - 2^5 */ square(t0,t1); /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); /* 2^11 - 2^1 */ square(t0,z2_10_0); /* 2^12 - 2^2 */ square(t1,t0); /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); /* 2^21 - 2^1 */ square(t0,z2_20_0); /* 2^22 - 2^2 */ square(t1,t0); /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); /* 2^41 - 2^1 */ square(t1,t0); /* 2^42 - 2^2 */ square(t0,t1); /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); /* 2^51 - 2^1 */ square(t0,z2_50_0); /* 2^52 - 2^2 */ square(t1,t0); /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); /* 2^101 - 2^1 */ square(t1,z2_100_0); /* 2^102 - 2^2 */ square(t0,t1); /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); /* 2^201 - 2^1 */ square(t0,t1); /* 2^202 - 2^2 */ square(t1,t0); /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); /* 2^251 - 2^1 */ square(t1,t0); /* 2^252 - 2^2 */ square(t0,t1); /* 2^253 - 2^3 */ square(t1,t0); /* 2^254 - 2^4 */ square(t0,t1); /* 2^255 - 2^5 */ square(t1,t0); /* 2^255 - 21 */ mult(out,t1,z11); } int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, const unsigned char *p) { unsigned int work[96]; unsigned char e[32]; unsigned int i; for (i = 0;i < 32;++i) e[i] = n[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; for (i = 0;i < 32;++i) work[i] = p[i]; mainloop(work,e); recip(work + 32,work + 32); mult(work + 64,work,work + 32); freeze(work + 64); for (i = 0;i < 32;++i) q[i] = work[64 + i]; return 0; } openssh-7.2p2/ssh-add.1010064400017500001750000000151351267006270000130640ustar00djmdjm.\" $OpenBSD: ssh-add.1,v 1.62 2015/03/30 18:28:37 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd $Mdocdate: March 30 2015 $ .Dt SSH-ADD 1 .Os .Sh NAME .Nm ssh-add .Nd adds private key identities to the authentication agent .Sh SYNOPSIS .Nm ssh-add .Op Fl cDdkLlXx .Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar .Nm ssh-add .Fl s Ar pkcs11 .Nm ssh-add .Fl e Ar pkcs11 .Sh DESCRIPTION .Nm adds private key identities to the authentication agent, .Xr ssh-agent 1 . When run without arguments, it adds the files .Pa ~/.ssh/id_rsa , .Pa ~/.ssh/id_dsa , .Pa ~/.ssh/id_ecdsa , .Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/identity . After loading a private key, .Nm will try to load corresponding certificate information from the filename obtained by appending .Pa -cert.pub to the name of the private key file. Alternative file names can be given on the command line. .Pp If any file requires a passphrase, .Nm asks for the passphrase from the user. The passphrase is read from the user's tty. .Nm retries the last passphrase if multiple identity files are given. .Pp The authentication agent must be running and the .Ev SSH_AUTH_SOCK environment variable must contain the name of its socket for .Nm to work. .Pp The options are as follows: .Bl -tag -width Ds .It Fl c Indicates that added identities should be subject to confirmation before being used for authentication. Confirmation is performed by .Xr ssh-askpass 1 . Successful confirmation is signaled by a zero exit status from .Xr ssh-askpass 1 , rather than text entered into the requester. .It Fl D Deletes all identities from the agent. .It Fl d Instead of adding identities, removes identities from the agent. If .Nm has been run without arguments, the keys for the default identities and their corresponding certificates will be removed. Otherwise, the argument list will be interpreted as a list of paths to public key files to specify keys and certificates to be removed from the agent. If no public key is found at a given path, .Nm will append .Pa .pub and retry. .It Fl E Ar fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: .Dq md5 and .Dq sha256 . The default is .Dq sha256 . .It Fl e Ar pkcs11 Remove keys provided by the PKCS#11 shared library .Ar pkcs11 . .It Fl k When loading keys into or deleting keys from the agent, process plain private keys only and skip certificates. .It Fl L Lists public key parameters of all identities currently represented by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. .It Fl s Ar pkcs11 Add keys provided by the PKCS#11 shared library .Ar pkcs11 . .It Fl t Ar life Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format specified in .Xr sshd_config 5 . .It Fl X Unlock the agent. .It Fl x Lock the agent with a password. .El .Sh ENVIRONMENT .Bl -tag -width Ds .It Ev "DISPLAY" and "SSH_ASKPASS" If .Nm needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If .Nm does not have a terminal associated with it but .Ev DISPLAY and .Ev SSH_ASKPASS are set, it will execute the program specified by .Ev SSH_ASKPASS (by default .Dq ssh-askpass ) and open an X11 window to read the passphrase. This is particularly useful when calling .Nm from a .Pa .xsession or related script. (Note that on some machines it may be necessary to redirect the input from .Pa /dev/null to make this work.) .It Ev SSH_AUTH_SOCK Identifies the path of a .Ux Ns -domain socket used to communicate with the agent. .El .Sh FILES .Bl -tag -width Ds .It Pa ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of the user. .It Pa ~/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_ecdsa Contains the protocol version 2 ECDSA authentication identity of the user. .It Pa ~/.ssh/id_ed25519 Contains the protocol version 2 Ed25519 authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .El .Pp Identity files should not be readable by anyone but the user. Note that .Nm ignores identity files if they are accessible by others. .Sh EXIT STATUS Exit status is 0 on success, 1 if the specified command fails, and 2 if .Nm is unable to contact the authentication agent. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-agent 1 , .Xr ssh-askpass 1 , .Xr ssh-keygen 1 , .Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.2p2/ssh-add.c010064400017500001750000000373641267006270000131560ustar00djmdjm/* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Adds an identity to the authentication server, or removes an identity. * * 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, 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 #include #include #include "openbsd-compat/openssl-compat.h" #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssh.h" #include "rsa.h" #include "log.h" #include "sshkey.h" #include "sshbuf.h" #include "authfd.h" #include "authfile.h" #include "pathnames.h" #include "misc.h" #include "ssherr.h" #include "digest.h" /* argv0 */ extern char *__progname; /* Default files to add */ static char *default_files[] = { #ifdef WITH_OPENSSL _PATH_SSH_CLIENT_ID_RSA, _PATH_SSH_CLIENT_ID_DSA, #ifdef OPENSSL_HAS_ECC _PATH_SSH_CLIENT_ID_ECDSA, #endif #endif /* WITH_OPENSSL */ _PATH_SSH_CLIENT_ID_ED25519, #ifdef WITH_SSH1 _PATH_SSH_CLIENT_IDENTITY, #endif NULL }; static int fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Default lifetime (0 == forever) */ static int lifetime = 0; /* User has to confirm key use */ static int confirm = 0; /* we keep a cache of one passphrase */ static char *pass = NULL; static void clear_pass(void) { if (pass) { explicit_bzero(pass, strlen(pass)); free(pass); pass = NULL; } } static int delete_file(int agent_fd, const char *filename, int key_only) { struct sshkey *public, *cert = NULL; char *certpath = NULL, *comment = NULL; int r, ret = -1; if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { printf("Bad key file %s: %s\n", filename, ssh_err(r)); return -1; } if ((r = ssh_remove_identity(agent_fd, public)) == 0) { fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); ret = 0; } else fprintf(stderr, "Could not remove identity \"%s\": %s\n", filename, ssh_err(r)); if (key_only) goto out; /* Now try to delete the corresponding certificate too */ free(comment); comment = NULL; xasprintf(&certpath, "%s-cert.pub", filename); if ((r = sshkey_load_public(certpath, &cert, &comment)) != 0) { if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) error("Failed to load certificate \"%s\": %s", certpath, ssh_err(r)); goto out; } if (!sshkey_equal_public(cert, public)) fatal("Certificate %s does not match private key %s", certpath, filename); if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { fprintf(stderr, "Identity removed: %s (%s)\n", certpath, comment); ret = 0; } else fprintf(stderr, "Could not remove identity \"%s\": %s\n", certpath, ssh_err(r)); out: sshkey_free(cert); sshkey_free(public); free(certpath); free(comment); return ret; } /* Send a request to remove all identities. */ static int delete_all(int agent_fd) { int ret = -1; if (ssh_remove_all_identities(agent_fd, 2) == 0) ret = 0; /* ignore error-code for ssh1 */ ssh_remove_all_identities(agent_fd, 1); if (ret == 0) fprintf(stderr, "All identities removed.\n"); else fprintf(stderr, "Failed to remove all identities.\n"); return ret; } static int add_file(int agent_fd, const char *filename, int key_only) { struct sshkey *private, *cert; char *comment = NULL; char msg[1024], *certpath = NULL; int r, fd, ret = -1; struct sshbuf *keyblob; if (strcmp(filename, "-") == 0) { fd = STDIN_FILENO; filename = "(stdin)"; } else if ((fd = open(filename, O_RDONLY)) < 0) { perror(filename); return -1; } /* * Since we'll try to load a keyfile multiple times, permission errors * will occur multiple times, so check perms first and bail if wrong. */ if (fd != STDIN_FILENO) { if (sshkey_perm_ok(fd, filename) != 0) { close(fd); return -1; } } if ((keyblob = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshkey_load_file(fd, keyblob)) != 0) { fprintf(stderr, "Error loading key \"%s\": %s\n", filename, ssh_err(r)); sshbuf_free(keyblob); close(fd); return -1; } close(fd); /* At first, try empty passphrase */ if ((r = sshkey_parse_private_fileblob(keyblob, "", &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) { fprintf(stderr, "Error loading key \"%s\": %s\n", filename, ssh_err(r)); goto fail_load; } /* try last */ if (private == NULL && pass != NULL) { if ((r = sshkey_parse_private_fileblob(keyblob, pass, &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) { fprintf(stderr, "Error loading key \"%s\": %s\n", filename, ssh_err(r)); goto fail_load; } } if (private == NULL) { /* clear passphrase since it did not work */ clear_pass(); snprintf(msg, sizeof msg, "Enter passphrase for %s%s: ", filename, confirm ? " (will confirm each use)" : ""); for (;;) { pass = read_passphrase(msg, RP_ALLOW_STDIN); if (strcmp(pass, "") == 0) goto fail_load; if ((r = sshkey_parse_private_fileblob(keyblob, pass, &private, &comment)) == 0) break; else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { fprintf(stderr, "Error loading key \"%s\": %s\n", filename, ssh_err(r)); fail_load: clear_pass(); sshbuf_free(keyblob); return -1; } clear_pass(); snprintf(msg, sizeof msg, "Bad passphrase, try again for %s%s: ", filename, confirm ? " (will confirm each use)" : ""); } } if (comment == NULL || *comment == '\0') comment = xstrdup(filename); sshbuf_free(keyblob); if ((r = ssh_add_identity_constrained(agent_fd, private, comment, lifetime, confirm)) == 0) { fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); ret = 0; if (lifetime != 0) fprintf(stderr, "Lifetime set to %d seconds\n", lifetime); if (confirm != 0) fprintf(stderr, "The user must confirm each use of the key\n"); } else { fprintf(stderr, "Could not add identity \"%s\": %s\n", filename, ssh_err(r)); } /* Skip trying to load the cert if requested */ if (key_only) goto out; /* Now try to add the certificate flavour too */ xasprintf(&certpath, "%s-cert.pub", filename); if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) { if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) error("Failed to load certificate \"%s\": %s", certpath, ssh_err(r)); goto out; } if (!sshkey_equal_public(cert, private)) { error("Certificate %s does not match private key %s", certpath, filename); sshkey_free(cert); goto out; } /* Graft with private bits */ if ((r = sshkey_to_certified(private)) != 0) { error("%s: sshkey_to_certified: %s", __func__, ssh_err(r)); sshkey_free(cert); goto out; } if ((r = sshkey_cert_copy(cert, private)) != 0) { error("%s: key_cert_copy: %s", __func__, ssh_err(r)); sshkey_free(cert); goto out; } sshkey_free(cert); if ((r = ssh_add_identity_constrained(agent_fd, private, comment, lifetime, confirm)) != 0) { error("Certificate %s (%s) add failed: %s", certpath, private->cert->key_id, ssh_err(r)); goto out; } fprintf(stderr, "Certificate added: %s (%s)\n", certpath, private->cert->key_id); if (lifetime != 0) fprintf(stderr, "Lifetime set to %d seconds\n", lifetime); if (confirm != 0) fprintf(stderr, "The user must confirm each use of the key\n"); out: free(certpath); free(comment); sshkey_free(private); return ret; } static int update_card(int agent_fd, int add, const char *id) { char *pin = NULL; int r, ret = -1; if (add) { if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; } if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin, lifetime, confirm)) == 0) { fprintf(stderr, "Card %s: %s\n", add ? "added" : "removed", id); ret = 0; } else { fprintf(stderr, "Could not %s card \"%s\": %s\n", add ? "add" : "remove", id, ssh_err(r)); ret = -1; } free(pin); return ret; } static int list_identities(int agent_fd, int do_fp) { char *fp; int r, had_identities = 0; struct ssh_identitylist *idlist; size_t i; #ifdef WITH_SSH1 int version = 1; #else int version = 2; #endif for (; version <= 2; version++) { if ((r = ssh_fetch_identitylist(agent_fd, version, &idlist)) != 0) { if (r != SSH_ERR_AGENT_NO_IDENTITIES) fprintf(stderr, "error fetching identities for " "protocol %d: %s\n", version, ssh_err(r)); continue; } for (i = 0; i < idlist->nkeys; i++) { had_identities = 1; if (do_fp) { fp = sshkey_fingerprint(idlist->keys[i], fingerprint_hash, SSH_FP_DEFAULT); printf("%u %s %s (%s)\n", sshkey_size(idlist->keys[i]), fp == NULL ? "(null)" : fp, idlist->comments[i], sshkey_type(idlist->keys[i])); free(fp); } else { if ((r = sshkey_write(idlist->keys[i], stdout)) != 0) { fprintf(stderr, "sshkey_write: %s\n", ssh_err(r)); continue; } fprintf(stdout, " %s\n", idlist->comments[i]); } } ssh_free_identitylist(idlist); } if (!had_identities) { printf("The agent has no identities.\n"); return -1; } return 0; } static int lock_agent(int agent_fd, int lock) { char prompt[100], *p1, *p2; int r, passok = 1, ret = -1; strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); p1 = read_passphrase(prompt, RP_ALLOW_STDIN); if (lock) { strlcpy(prompt, "Again: ", sizeof prompt); p2 = read_passphrase(prompt, RP_ALLOW_STDIN); if (strcmp(p1, p2) != 0) { fprintf(stderr, "Passwords do not match.\n"); passok = 0; } explicit_bzero(p2, strlen(p2)); free(p2); } if (passok) { if ((r = ssh_lock_agent(agent_fd, lock, p1)) == 0) { fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); ret = 0; } else { fprintf(stderr, "Failed to %slock agent: %s\n", lock ? "" : "un", ssh_err(r)); } } explicit_bzero(p1, strlen(p1)); free(p1); return (ret); } static int do_file(int agent_fd, int deleting, int key_only, char *file) { if (deleting) { if (delete_file(agent_fd, file, key_only) == -1) return -1; } else { if (add_file(agent_fd, file, key_only) == -1) return -1; } return 0; } static void usage(void) { fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -l List fingerprints of all identities.\n"); fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n"); fprintf(stderr, " -L List public key parameters of all identities.\n"); fprintf(stderr, " -k Load only keys and not certificates.\n"); fprintf(stderr, " -c Require confirmation to sign using identities\n"); fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n"); fprintf(stderr, " -d Delete identity.\n"); fprintf(stderr, " -D Delete all identities.\n"); fprintf(stderr, " -x Lock agent.\n"); fprintf(stderr, " -X Unlock agent.\n"); fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); } int main(int argc, char **argv) { extern char *optarg; extern int optind; int agent_fd; char *pkcs11provider = NULL; int r, i, ch, deleting = 0, ret = 0, key_only = 0; int xflag = 0, lflag = 0, Dflag = 0; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); __progname = ssh_get_progname(argv[0]); seed_rng(); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif setvbuf(stdout, NULL, _IOLBF, 0); /* First, get a connection to the authentication agent. */ switch (r = ssh_get_authentication_socket(&agent_fd)) { case 0: break; case SSH_ERR_AGENT_NOT_PRESENT: fprintf(stderr, "Could not open a connection to your " "authentication agent.\n"); exit(2); default: fprintf(stderr, "Error connecting to agent: %s\n", ssh_err(r)); exit(2); } while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) fatal("Invalid hash algorithm \"%s\"", optarg); break; case 'k': key_only = 1; break; case 'l': case 'L': if (lflag != 0) fatal("-%c flag already specified", lflag); lflag = ch; break; case 'x': case 'X': if (xflag != 0) fatal("-%c flag already specified", xflag); xflag = ch; break; case 'c': confirm = 1; break; case 'd': deleting = 1; break; case 'D': Dflag = 1; break; case 's': pkcs11provider = optarg; break; case 'e': deleting = 1; pkcs11provider = optarg; break; case 't': if ((lifetime = convtime(optarg)) == -1) { fprintf(stderr, "Invalid lifetime\n"); ret = 1; goto done; } break; default: usage(); ret = 1; goto done; } } if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) fatal("Invalid combination of actions"); else if (xflag) { if (lock_agent(agent_fd, xflag == 'x' ? 1 : 0) == -1) ret = 1; goto done; } else if (lflag) { if (list_identities(agent_fd, lflag == 'l' ? 1 : 0) == -1) ret = 1; goto done; } else if (Dflag) { if (delete_all(agent_fd) == -1) ret = 1; goto done; } argc -= optind; argv += optind; if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider) == -1) ret = 1; goto done; } if (argc == 0) { char buf[PATH_MAX]; struct passwd *pw; struct stat st; int count = 0; if ((pw = getpwuid(getuid())) == NULL) { fprintf(stderr, "No user found with uid %u\n", (u_int)getuid()); ret = 1; goto done; } for (i = 0; default_files[i]; i++) { snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, default_files[i]); if (stat(buf, &st) < 0) continue; if (do_file(agent_fd, deleting, key_only, buf) == -1) ret = 1; else count++; } if (count == 0) ret = 1; } else { for (i = 0; i < argc; i++) { if (do_file(agent_fd, deleting, key_only, argv[i]) == -1) ret = 1; } } clear_pass(); done: ssh_close_authentication_socket(agent_fd); return ret; } openssh-7.2p2/ssh-agent.1010064400017500001750000000152331267006270000134310ustar00djmdjm.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd $Mdocdate: November 15 2015 $ .Dt SSH-AGENT 1 .Os .Sh NAME .Nm ssh-agent .Nd authentication agent .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s .Op Fl \&Dd .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar command Op Ar arg ... .Nm ssh-agent .Op Fl c | s .Fl k .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA, Ed25519). .Nm is usually started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using .Xr ssh 1 . .Pp The agent initially does not have any private keys. Keys are added using .Xr ssh 1 (see .Cm AddKeysToAgent in .Xr ssh_config 5 for details) or .Xr ssh-add 1 . Multiple identities may be stored in .Nm concurrently and .Xr ssh 1 will automatically use them if present. .Xr ssh-add 1 is also used to remove keys from .Nm and to query the keys that are held in one. .Pp The options are as follows: .Bl -tag -width Ds .It Fl a Ar bind_address Bind the agent to the .Ux Ns -domain socket .Ar bind_address . The default is .Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . .It Fl c Generate C-shell commands on .Dv stdout . This is the default if .Ev SHELL looks like it's a csh style of shell. .It Fl D Foreground mode. When this option is specified .Nm will not fork. .It Fl d Debug mode. When this option is specified .Nm will not fork and will write debug information to standard error. .It Fl E Ar fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: .Dq md5 and .Dq sha256 . The default is .Dq sha256 . .It Fl k Kill the current agent (given by the .Ev SSH_AGENT_PID environment variable). .It Fl s Generate Bourne shell commands on .Dv stdout . This is the default if .Ev SHELL does not look like it's a csh style of shell. .It Fl t Ar life Set a default value for the maximum lifetime of identities added to the agent. The lifetime may be specified in seconds or in a time format specified in .Xr sshd_config 5 . A lifetime specified for an identity with .Xr ssh-add 1 overrides this value. Without this option the default maximum lifetime is forever. .El .Pp If a command line is given, this is executed as a subprocess of the agent. When the command dies, so does the agent. .Pp The idea is that the agent is run in the user's local PC, laptop, or terminal. Authentication data need not be stored on any other machine, and authentication passphrases never go over the network. However, the connection to the agent is forwarded over SSH remote logins, and the user can thus use the privileges given by the identities anywhere in the network in a secure way. .Pp There are two main ways to get an agent set up: The first is that the agent starts a new subcommand into which some environment variables are exported, eg .Cm ssh-agent xterm & . The second is that the agent prints the needed shell commands (either .Xr sh 1 or .Xr csh 1 syntax can be generated) which can be evaluated in the calling shell, eg .Cm eval `ssh-agent -s` for Bourne-type shells such as .Xr sh 1 or .Xr ksh 1 and .Cm eval `ssh-agent -c` for .Xr csh 1 and derivatives. .Pp Later .Xr ssh 1 looks at these variables and uses them to establish a connection to the agent. .Pp The agent will never send a private key over its request channel. Instead, operations that require a private key will be performed by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent. .Pp A .Ux Ns -domain socket is created and the name of this socket is stored in the .Ev SSH_AUTH_SOCK environment variable. The socket is made accessible only to the current user. This method is easily abused by root or another instance of the same user. .Pp The .Ev SSH_AGENT_PID environment variable holds the agent's process ID. .Pp The agent exits automatically when the command given on the command line terminates. .Sh FILES .Bl -tag -width Ds .It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .Ux Ns -domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-keygen 1 , .Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.2p2/ssh-agent.c010064400017500001750000001067721267006270000135240ustar00djmdjm/* $OpenBSD: ssh-agent.c,v 1.212 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * The authentication agent program. * * 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, 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 /* MIN MAX */ #include #include #include #include #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_UN_H # include #endif #include "openbsd-compat/sys-queue.h" #ifdef WITH_OPENSSL #include #include "openbsd-compat/openssl-compat.h" #endif #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include #include #ifdef HAVE_UTIL_H # include #endif #include "xmalloc.h" #include "ssh.h" #include "rsa.h" #include "sshbuf.h" #include "sshkey.h" #include "authfd.h" #include "compat.h" #include "log.h" #include "misc.h" #include "digest.h" #include "ssherr.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif #if defined(HAVE_SYS_PRCTL_H) #include /* For prctl() and PR_SET_DUMPABLE */ #endif typedef enum { AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION } sock_type; typedef struct { int fd; sock_type type; struct sshbuf *input; struct sshbuf *output; struct sshbuf *request; } SocketEntry; u_int sockets_alloc = 0; SocketEntry *sockets = NULL; typedef struct identity { TAILQ_ENTRY(identity) next; struct sshkey *key; char *comment; char *provider; time_t death; u_int confirm; } Identity; typedef struct { int nentries; TAILQ_HEAD(idqueue, identity) idlist; } Idtab; /* private key table, one per protocol version */ Idtab idtable[3]; int max_fd = 0; /* pid of shell == parent of agent */ pid_t parent_pid = -1; time_t parent_alive_interval = 0; /* pid of process for which cleanup_socket is applicable */ pid_t cleanup_pid = 0; /* pathname and directory for AUTH_SOCKET */ char socket_name[PATH_MAX]; char socket_dir[PATH_MAX]; /* locking */ #define LOCK_SIZE 32 #define LOCK_SALT_SIZE 16 #define LOCK_ROUNDS 1 int locked = 0; char lock_passwd[LOCK_SIZE]; char lock_salt[LOCK_SALT_SIZE]; extern char *__progname; /* Default lifetime in seconds (0 == forever) */ static long lifetime = 0; static int fingerprint_hash = SSH_FP_HASH_DEFAULT; static void close_socket(SocketEntry *e) { close(e->fd); e->fd = -1; e->type = AUTH_UNUSED; sshbuf_free(e->input); sshbuf_free(e->output); sshbuf_free(e->request); } static void idtab_init(void) { int i; for (i = 0; i <=2; i++) { TAILQ_INIT(&idtable[i].idlist); idtable[i].nentries = 0; } } /* return private key table for requested protocol version */ static Idtab * idtab_lookup(int version) { if (version < 1 || version > 2) fatal("internal error, bad protocol version %d", version); return &idtable[version]; } static void free_identity(Identity *id) { sshkey_free(id->key); free(id->provider); free(id->comment); free(id); } /* return matching private key for given public key */ static Identity * lookup_identity(struct sshkey *key, int version) { Identity *id; Idtab *tab = idtab_lookup(version); TAILQ_FOREACH(id, &tab->idlist, next) { if (sshkey_equal(key, id->key)) return (id); } return (NULL); } /* Check confirmation of keysign request */ static int confirm_key(Identity *id) { char *p; int ret = -1; p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); if (p != NULL && ask_permission("Allow use of key %s?\nKey fingerprint %s.", id->comment, p)) ret = 0; free(p); return (ret); } static void send_status(SocketEntry *e, int success) { int r; if ((r = sshbuf_put_u32(e->output, 1)) != 0 || (r = sshbuf_put_u8(e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } /* send list of supported public keys to 'client' */ static void process_request_identities(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); Identity *id; struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, (version == 1) ? SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || (r = sshbuf_put_u32(msg, tab->nentries)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); TAILQ_FOREACH(id, &tab->idlist, next) { if (id->key->type == KEY_RSA1) { #ifdef WITH_SSH1 if ((r = sshbuf_put_u32(msg, BN_num_bits(id->key->rsa->n))) != 0 || (r = sshbuf_put_bignum1(msg, id->key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, id->key->rsa->n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); #endif } else { u_char *blob; size_t blen; if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) { error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); continue; } if ((r = sshbuf_put_string(msg, blob, blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); free(blob); } if ((r = sshbuf_put_cstring(msg, id->comment)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } if ((r = sshbuf_put_stringb(e->output, msg)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(msg); } #ifdef WITH_SSH1 /* ssh1 only */ static void process_authentication_challenge1(SocketEntry *e) { u_char buf[32], mdbuf[16], session_id[16]; u_int response_type; BIGNUM *challenge; Identity *id; int r, len; struct sshbuf *msg; struct ssh_digest_ctx *md; struct sshkey *key; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((key = sshkey_new(KEY_RSA1)) == NULL) fatal("%s: sshkey_new failed", __func__); if ((challenge = BN_new()) == NULL) fatal("%s: BN_new failed", __func__); if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || (r = sshbuf_get_bignum1(e->request, challenge))) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* Only protocol 1.1 is supported */ if (sshbuf_len(e->request) == 0) goto failure; if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 || (r = sshbuf_get_u32(e->request, &response_type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (response_type != 1) goto failure; id = lookup_identity(key, 1); if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { struct sshkey *private = id->key; /* Decrypt the challenge using the private key. */ if ((r = rsa_private_decrypt(challenge, challenge, private->rsa) != 0)) { fatal("%s: rsa_public_encrypt: %s", __func__, ssh_err(r)); goto failure; /* XXX ? */ } /* The response is MD5 of decrypted challenge plus session id */ len = BN_num_bytes(challenge); if (len <= 0 || len > 32) { logit("%s: bad challenge length %d", __func__, len); goto failure; } memset(buf, 0, 32); BN_bn2bin(challenge, buf + 32 - len); if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || ssh_digest_update(md, buf, 32) < 0 || ssh_digest_update(md, session_id, 16) < 0 || ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0) fatal("%s: md5 failed", __func__); ssh_digest_free(md); /* Send the response. */ if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 || (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); goto send; } failure: /* Unknown identity or protocol error. Send failure. */ if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send: if ((r = sshbuf_put_stringb(e->output, msg)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshkey_free(key); BN_clear_free(challenge); sshbuf_free(msg); } #endif static char * agent_decode_alg(struct sshkey *key, u_int flags) { if (key->type == KEY_RSA) { if (flags & SSH_AGENT_RSA_SHA2_256) return "rsa-sha2-256"; else if (flags & SSH_AGENT_RSA_SHA2_512) return "rsa-sha2-512"; } return NULL; } /* ssh2 only */ static void process_sign_request2(SocketEntry *e) { u_char *blob, *data, *signature = NULL; size_t blen, dlen, slen = 0; u_int compat = 0, flags; int r, ok = -1; struct sshbuf *msg; struct sshkey *key; struct identity *id; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 || (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 || (r = sshbuf_get_u32(e->request, &flags)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (flags & SSH_AGENT_OLD_SIGNATURE) compat = SSH_BUG_SIGBLOB; if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { error("%s: cannot parse key blob: %s", __func__, ssh_err(r)); goto send; } if ((id = lookup_identity(key, 2)) == NULL) { verbose("%s: %s key not found", __func__, sshkey_type(key)); goto send; } if (id->confirm && confirm_key(id) != 0) { verbose("%s: user refused key", __func__); goto send; } if ((r = sshkey_sign(id->key, &signature, &slen, data, dlen, agent_decode_alg(key, flags), compat)) != 0) { error("%s: sshkey_sign: %s", __func__, ssh_err(r)); goto send; } /* Success */ ok = 0; send: sshkey_free(key); if (ok == 0) { if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || (r = sshbuf_put_string(msg, signature, slen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((r = sshbuf_put_stringb(e->output, msg)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(msg); free(data); free(blob); free(signature); } /* shared */ static void process_remove_identity(SocketEntry *e, int version) { size_t blen; int r, success = 0; struct sshkey *key = NULL; u_char *blob; #ifdef WITH_SSH1 u_int bits; #endif /* WITH_SSH1 */ switch (version) { #ifdef WITH_SSH1 case 1: if ((key = sshkey_new(KEY_RSA1)) == NULL) { error("%s: sshkey_new failed", __func__); return; } if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (bits != sshkey_size(key)) logit("Warning: identity keysize mismatch: " "actual %u, announced %u", sshkey_size(key), bits); break; #endif /* WITH_SSH1 */ case 2: if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((r = sshkey_from_blob(blob, blen, &key)) != 0) error("%s: sshkey_from_blob failed: %s", __func__, ssh_err(r)); free(blob); break; } if (key != NULL) { Identity *id = lookup_identity(key, version); if (id != NULL) { /* * We have this key. Free the old key. Since we * don't want to leave empty slots in the middle of * the array, we actually free the key there and move * all the entries between the empty slot and the end * of the array. */ Idtab *tab = idtab_lookup(version); if (tab->nentries < 1) fatal("process_remove_identity: " "internal error: tab->nentries %d", tab->nentries); TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); tab->nentries--; success = 1; } sshkey_free(key); } send_status(e, success); } static void process_remove_all_identities(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); Identity *id; /* Loop over all identities and clear the keys. */ for (id = TAILQ_FIRST(&tab->idlist); id; id = TAILQ_FIRST(&tab->idlist)) { TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); } /* Mark that there are no identities. */ tab->nentries = 0; /* Send success. */ send_status(e, 1); } /* removes expired keys and returns number of seconds until the next expiry */ static time_t reaper(void) { time_t deadline = 0, now = monotime(); Identity *id, *nxt; int version; Idtab *tab; for (version = 1; version < 3; version++) { tab = idtab_lookup(version); for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); if (id->death == 0) continue; if (now >= id->death) { debug("expiring key '%s'", id->comment); TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); tab->nentries--; } else deadline = (deadline == 0) ? id->death : MIN(deadline, id->death); } } if (deadline == 0 || deadline <= now) return 0; else return (deadline - now); } /* * XXX this and the corresponding serialisation function probably belongs * in key.c */ #ifdef WITH_SSH1 static int agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp) { struct sshkey *k = NULL; int r = SSH_ERR_INTERNAL_ERROR; *kp = NULL; if ((k = sshkey_new_private(KEY_RSA1)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || /* SSH1 and SSL have p and q swapped */ (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ goto out; /* Generate additional parameters */ if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) goto out; /* enable blinding */ if (RSA_blinding_on(k->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; /* success */ out: if (r == 0) *kp = k; else sshkey_free(k); return r; } #endif /* WITH_SSH1 */ static void process_add_identity(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); Identity *id; int success = 0, confirm = 0; u_int seconds; char *comment = NULL; time_t death = 0; struct sshkey *k = NULL; u_char ctype; int r = SSH_ERR_INTERNAL_ERROR; switch (version) { #ifdef WITH_SSH1 case 1: r = agent_decode_rsa1(e->request, &k); break; #endif /* WITH_SSH1 */ case 2: r = sshkey_private_deserialize(e->request, &k); break; } if (r != 0 || k == NULL || (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { error("%s: decode private key: %s", __func__, ssh_err(r)); goto err; } while (sshbuf_len(e->request)) { if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); goto err; } switch (ctype) { case SSH_AGENT_CONSTRAIN_LIFETIME: if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) { error("%s: bad lifetime constraint: %s", __func__, ssh_err(r)); goto err; } death = monotime() + seconds; break; case SSH_AGENT_CONSTRAIN_CONFIRM: confirm = 1; break; default: error("%s: Unknown constraint %d", __func__, ctype); err: sshbuf_reset(e->request); free(comment); sshkey_free(k); goto send; } } success = 1; if (lifetime && !death) death = monotime() + lifetime; if ((id = lookup_identity(k, version)) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ tab->nentries++; } else { sshkey_free(k); free(id->comment); } id->comment = comment; id->death = death; id->confirm = confirm; send: send_status(e, success); } /* XXX todo: encrypt sensitive data with passphrase */ static void process_lock_agent(SocketEntry *e, int lock) { int r, success = 0, delay; char *passwd, passwdhash[LOCK_SIZE]; static u_int fail_count = 0; size_t pwlen; if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (pwlen == 0) { debug("empty password not supported"); } else if (locked && !lock) { if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0) fatal("bcrypt_pbkdf"); if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) { debug("agent unlocked"); locked = 0; fail_count = 0; explicit_bzero(lock_passwd, sizeof(lock_passwd)); success = 1; } else { /* delay in 0.1s increments up to 10s */ if (fail_count < 100) fail_count++; delay = 100000 * fail_count; debug("unlock failed, delaying %0.1lf seconds", (double)delay/1000000); usleep(delay); } explicit_bzero(passwdhash, sizeof(passwdhash)); } else if (!locked && lock) { debug("agent locked"); locked = 1; arc4random_buf(lock_salt, sizeof(lock_salt)); if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0) fatal("bcrypt_pbkdf"); success = 1; } explicit_bzero(passwd, pwlen); free(passwd); send_status(e, success); } static void no_identities(SocketEntry *e, u_int type) { struct sshbuf *msg; int r; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || (r = sshbuf_put_u32(msg, 0)) != 0 || (r = sshbuf_put_stringb(e->output, msg)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(msg); } #ifdef ENABLE_PKCS11 static void process_add_smartcard_key(SocketEntry *e) { char *provider = NULL, *pin; int r, i, version, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; u_char type; struct sshkey **keys = NULL, *k; Identity *id; Idtab *tab; if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); while (sshbuf_len(e->request)) { if ((r = sshbuf_get_u8(e->request, &type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); switch (type) { case SSH_AGENT_CONSTRAIN_LIFETIME: if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); death = monotime() + seconds; break; case SSH_AGENT_CONSTRAIN_CONFIRM: confirm = 1; break; default: error("process_add_smartcard_key: " "Unknown constraint type %d", type); goto send; } } if (lifetime && !death) death = monotime() + lifetime; count = pkcs11_add_provider(provider, pin, &keys); for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; tab = idtab_lookup(version); if (lookup_identity(k, version) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; id->provider = xstrdup(provider); id->comment = xstrdup(provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); tab->nentries++; success = 1; } else { sshkey_free(k); } keys[i] = NULL; } send: free(pin); free(provider); free(keys); send_status(e, success); } static void process_remove_smartcard_key(SocketEntry *e) { char *provider = NULL, *pin = NULL; int r, version, success = 0; Identity *id, *nxt; Idtab *tab; if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); free(pin); for (version = 1; version < 3; version++) { tab = idtab_lookup(version); for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); /* Skip file--based keys */ if (id->provider == NULL) continue; if (!strcmp(provider, id->provider)) { TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); tab->nentries--; } } } if (pkcs11_del_provider(provider) == 0) success = 1; else error("process_remove_smartcard_key:" " pkcs11_del_provider failed"); free(provider); send_status(e, success); } #endif /* ENABLE_PKCS11 */ /* dispatch incoming messages */ static void process_message(SocketEntry *e) { u_int msg_len; u_char type; const u_char *cp; int r; if (sshbuf_len(e->input) < 5) return; /* Incomplete message. */ cp = sshbuf_ptr(e->input); msg_len = PEEK_U32(cp); if (msg_len > 256 * 1024) { close_socket(e); return; } if (sshbuf_len(e->input) < msg_len + 4) return; /* move the current input to e->request */ sshbuf_reset(e->request); if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || (r = sshbuf_get_u8(e->request, &type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* check wheter agent is locked */ if (locked && type != SSH_AGENTC_UNLOCK) { sshbuf_reset(e->request); switch (type) { case SSH_AGENTC_REQUEST_RSA_IDENTITIES: case SSH2_AGENTC_REQUEST_IDENTITIES: /* send empty lists */ no_identities(e, type); break; default: /* send a fail message for all other request types */ send_status(e, 0); } return; } debug("type %d", type); switch (type) { case SSH_AGENTC_LOCK: case SSH_AGENTC_UNLOCK: process_lock_agent(e, type == SSH_AGENTC_LOCK); break; #ifdef WITH_SSH1 /* ssh1 */ case SSH_AGENTC_RSA_CHALLENGE: process_authentication_challenge1(e); break; case SSH_AGENTC_REQUEST_RSA_IDENTITIES: process_request_identities(e, 1); break; case SSH_AGENTC_ADD_RSA_IDENTITY: case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED: process_add_identity(e, 1); break; case SSH_AGENTC_REMOVE_RSA_IDENTITY: process_remove_identity(e, 1); break; #endif case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */ break; /* ssh2 */ case SSH2_AGENTC_SIGN_REQUEST: process_sign_request2(e); break; case SSH2_AGENTC_REQUEST_IDENTITIES: process_request_identities(e, 2); break; case SSH2_AGENTC_ADD_IDENTITY: case SSH2_AGENTC_ADD_ID_CONSTRAINED: process_add_identity(e, 2); break; case SSH2_AGENTC_REMOVE_IDENTITY: process_remove_identity(e, 2); break; case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: process_remove_all_identities(e, 2); break; #ifdef ENABLE_PKCS11 case SSH_AGENTC_ADD_SMARTCARD_KEY: case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: process_add_smartcard_key(e); break; case SSH_AGENTC_REMOVE_SMARTCARD_KEY: process_remove_smartcard_key(e); break; #endif /* ENABLE_PKCS11 */ default: /* Unknown message. Respond with failure. */ error("Unknown message %d", type); sshbuf_reset(e->request); send_status(e, 0); break; } } static void new_socket(sock_type type, int fd) { u_int i, old_alloc, new_alloc; set_nonblock(fd); if (fd > max_fd) max_fd = fd; for (i = 0; i < sockets_alloc; i++) if (sockets[i].type == AUTH_UNUSED) { sockets[i].fd = fd; if ((sockets[i].input = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((sockets[i].output = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((sockets[i].request = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); sockets[i].type = type; return; } old_alloc = sockets_alloc; new_alloc = sockets_alloc + 10; sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0])); for (i = old_alloc; i < new_alloc; i++) sockets[i].type = AUTH_UNUSED; sockets_alloc = new_alloc; sockets[old_alloc].fd = fd; if ((sockets[old_alloc].input = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((sockets[old_alloc].output = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((sockets[old_alloc].request = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); sockets[old_alloc].type = type; } static int prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, struct timeval **tvpp) { u_int i, sz; int n = 0; static struct timeval tv; time_t deadline; for (i = 0; i < sockets_alloc; i++) { switch (sockets[i].type) { case AUTH_SOCKET: case AUTH_CONNECTION: n = MAX(n, sockets[i].fd); break; case AUTH_UNUSED: break; default: fatal("Unknown socket type %d", sockets[i].type); break; } } sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); if (*fdrp == NULL || sz > *nallocp) { free(*fdrp); free(*fdwp); *fdrp = xmalloc(sz); *fdwp = xmalloc(sz); *nallocp = sz; } if (n < *fdl) debug("XXX shrink: %d < %d", n, *fdl); *fdl = n; memset(*fdrp, 0, sz); memset(*fdwp, 0, sz); for (i = 0; i < sockets_alloc; i++) { switch (sockets[i].type) { case AUTH_SOCKET: case AUTH_CONNECTION: FD_SET(sockets[i].fd, *fdrp); if (sshbuf_len(sockets[i].output) > 0) FD_SET(sockets[i].fd, *fdwp); break; default: break; } } deadline = reaper(); if (parent_alive_interval != 0) deadline = (deadline == 0) ? parent_alive_interval : MIN(deadline, parent_alive_interval); if (deadline == 0) { *tvpp = NULL; } else { tv.tv_sec = deadline; tv.tv_usec = 0; *tvpp = &tv; } return (1); } static void after_select(fd_set *readset, fd_set *writeset) { struct sockaddr_un sunaddr; socklen_t slen; char buf[1024]; int len, sock, r; u_int i, orig_alloc; uid_t euid; gid_t egid; for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++) switch (sockets[i].type) { case AUTH_UNUSED: break; case AUTH_SOCKET: if (FD_ISSET(sockets[i].fd, readset)) { slen = sizeof(sunaddr); sock = accept(sockets[i].fd, (struct sockaddr *)&sunaddr, &slen); if (sock < 0) { error("accept from AUTH_SOCKET: %s", strerror(errno)); break; } if (getpeereid(sock, &euid, &egid) < 0) { error("getpeereid %d failed: %s", sock, strerror(errno)); close(sock); break; } if ((euid != 0) && (getuid() != euid)) { error("uid mismatch: " "peer euid %u != uid %u", (u_int) euid, (u_int) getuid()); close(sock); break; } new_socket(AUTH_CONNECTION, sock); } break; case AUTH_CONNECTION: if (sshbuf_len(sockets[i].output) > 0 && FD_ISSET(sockets[i].fd, writeset)) { len = write(sockets[i].fd, sshbuf_ptr(sockets[i].output), sshbuf_len(sockets[i].output)); if (len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) continue; if (len <= 0) { close_socket(&sockets[i]); break; } if ((r = sshbuf_consume(sockets[i].output, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } if (FD_ISSET(sockets[i].fd, readset)) { len = read(sockets[i].fd, buf, sizeof(buf)); if (len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) continue; if (len <= 0) { close_socket(&sockets[i]); break; } if ((r = sshbuf_put(sockets[i].input, buf, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); explicit_bzero(buf, sizeof(buf)); process_message(&sockets[i]); } break; default: fatal("Unknown type %d", sockets[i].type); } } static void cleanup_socket(void) { if (cleanup_pid != 0 && getpid() != cleanup_pid) return; debug("%s: cleanup", __func__); if (socket_name[0]) unlink(socket_name); if (socket_dir[0]) rmdir(socket_dir); } void cleanup_exit(int i) { cleanup_socket(); _exit(i); } /*ARGSUSED*/ static void cleanup_handler(int sig) { cleanup_socket(); #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif _exit(2); } static void check_parent_exists(void) { /* * If our parent has exited then getppid() will return (pid_t)1, * so testing for that should be safe. */ if (parent_pid != -1 && getppid() != parent_pid) { /* printf("Parent has died - Authentication agent exiting.\n"); */ cleanup_socket(); _exit(2); } } static void usage(void) { fprintf(stderr, "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" " [-t life] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); exit(1); } int main(int ac, char **av) { int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; int sock, fd, ch, result, saved_errno; u_int nalloc; char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; #ifdef HAVE_SETRLIMIT struct rlimit rlim; #endif extern int optind; extern char *optarg; pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; struct timeval *tvp = NULL; size_t len; mode_t prev_mask; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); /* drop */ setegid(getgid()); setgid(getgid()); #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* Disable ptrace on Linux without sgid bit */ prctl(PR_SET_DUMPABLE, 0); #endif #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif __progname = ssh_get_progname(av[0]); seed_rng(); while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) fatal("Invalid hash algorithm \"%s\"", optarg); break; case 'c': if (s_flag) usage(); c_flag++; break; case 'k': k_flag++; break; case 's': if (c_flag) usage(); s_flag++; break; case 'd': if (d_flag || D_flag) usage(); d_flag++; break; case 'D': if (d_flag || D_flag) usage(); D_flag++; break; case 'a': agentsocket = optarg; break; case 't': if ((lifetime = convtime(optarg)) == -1) { fprintf(stderr, "Invalid lifetime\n"); usage(); } break; default: usage(); } } ac -= optind; av += optind; if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) usage(); if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); if (shell != NULL && (len = strlen(shell)) > 2 && strncmp(shell + len - 3, "csh", 3) == 0) c_flag = 1; } if (k_flag) { const char *errstr = NULL; pidstr = getenv(SSH_AGENTPID_ENV_NAME); if (pidstr == NULL) { fprintf(stderr, "%s not set, cannot kill agent\n", SSH_AGENTPID_ENV_NAME); exit(1); } pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); if (errstr) { fprintf(stderr, "%s=\"%s\", which is not a good PID: %s\n", SSH_AGENTPID_ENV_NAME, pidstr, errstr); exit(1); } if (kill(pid, SIGTERM) == -1) { perror("kill"); exit(1); } format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; printf(format, SSH_AUTHSOCKET_ENV_NAME); printf(format, SSH_AGENTPID_ENV_NAME); printf("echo Agent pid %ld killed;\n", (long)pid); exit(0); } parent_pid = getpid(); if (agentsocket == NULL) { /* Create private directory for agent socket */ mktemp_proto(socket_dir, sizeof(socket_dir)); if (mkdtemp(socket_dir) == NULL) { perror("mkdtemp: private socket dir"); exit(1); } snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, (long)parent_pid); } else { /* Try to use specified agent socket */ socket_dir[0] = '\0'; strlcpy(socket_name, agentsocket, sizeof socket_name); } /* * Create socket early so it will exist before command gets run from * the parent. */ prev_mask = umask(0177); sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); if (sock < 0) { /* XXX - unix_listener() calls error() not perror() */ *socket_name = '\0'; /* Don't unlink any existing file */ cleanup_exit(1); } umask(prev_mask); /* * Fork, and have the parent execute the command, if any, or present * the socket data. The child continues as the authentication agent. */ if (D_flag || d_flag) { log_init(__progname, d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 1); format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, SSH_AUTHSOCKET_ENV_NAME); printf("echo Agent pid %ld;\n", (long)parent_pid); fflush(stdout); goto skip; } pid = fork(); if (pid == -1) { perror("fork"); cleanup_exit(1); } if (pid != 0) { /* Parent - execute the given command. */ close(sock); snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); if (ac == 0) { format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, SSH_AUTHSOCKET_ENV_NAME); printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, SSH_AGENTPID_ENV_NAME); printf("echo Agent pid %ld;\n", (long)pid); exit(0); } if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { perror("setenv"); exit(1); } execvp(av[0], av); perror(av[0]); exit(1); } /* child */ log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); if (setsid() == -1) { error("setsid: %s", strerror(errno)); cleanup_exit(1); } (void)chdir("/"); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { /* XXX might close listen socket */ (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) close(fd); } #ifdef HAVE_SETRLIMIT /* deny core dumps, since memory contains unencrypted private keys */ rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) { error("setrlimit RLIMIT_CORE: %s", strerror(errno)); cleanup_exit(1); } #endif skip: cleanup_pid = getpid(); #ifdef ENABLE_PKCS11 pkcs11_init(0); #endif new_socket(AUTH_SOCKET, sock); if (ac > 0) parent_alive_interval = 10; idtab_init(); signal(SIGPIPE, SIG_IGN); signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); signal(SIGHUP, cleanup_handler); signal(SIGTERM, cleanup_handler); nalloc = 0; if (pledge("stdio cpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); platform_pledge_agent(); while (1) { prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); saved_errno = errno; if (parent_alive_interval != 0) check_parent_exists(); (void) reaper(); /* remove expired keys */ if (result < 0) { if (saved_errno == EINTR) continue; fatal("select: %s", strerror(saved_errno)); } else if (result > 0) after_select(readsetp, writesetp); } /* NOTREACHED */ } openssh-7.2p2/ssh-dss.c010064400017500001750000000133751267006270000132130ustar00djmdjm/* $OpenBSD: ssh-dss.c,v 1.34 2015/12/11 04:21:12 mmcc 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" #ifdef WITH_OPENSSL #include #include #include #include #include #include #include "sshbuf.h" #include "compat.h" #include "ssherr.h" #include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" #define INTBLOB_LEN 20 #define SIGBLOB_LEN (2*INTBLOB_LEN) int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { DSA_SIG *sig = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; int ret = SSH_ERR_INVALID_ARGUMENT; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA) return SSH_ERR_INVALID_ARGUMENT; if (dlen == 0) return SSH_ERR_INTERNAL_ERROR; if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, digest, sizeof(digest))) != 0) goto out; if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rlen = BN_num_bytes(sig->r); slen = BN_num_bytes(sig->s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } explicit_bzero(sigblob, SIGBLOB_LEN); BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); if (compat & SSH_BUG_SIGBLOB) { if (sigp != NULL) { if ((*sigp = malloc(SIGBLOB_LEN)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sigblob, SIGBLOB_LEN); } if (lenp != NULL) *lenp = SIGBLOB_LEN; ret = 0; } else { /* ietf-drafts */ if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if ((ret = sshbuf_put_cstring(b, "ssh-dss")) != 0 || (ret = sshbuf_put_string(b, sigblob, SIGBLOB_LEN)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sshbuf_ptr(b), len); } if (lenp != NULL) *lenp = len; ret = 0; } out: explicit_bzero(digest, sizeof(digest)); if (sig != NULL) DSA_SIG_free(sig); sshbuf_free(b); return ret; } int ssh_dss_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat) { DSA_SIG *sig = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; char *ktype = NULL; if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA) return SSH_ERR_INVALID_ARGUMENT; if (dlen == 0) return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ if (compat & SSH_BUG_SIGBLOB) { if ((sigblob = malloc(signaturelen)) == NULL) return SSH_ERR_ALLOC_FAIL; memcpy(sigblob, signature, signaturelen); len = signaturelen; } else { /* ietf-drafts */ if ((b = sshbuf_from(signature, signaturelen)) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_get_cstring(b, &ktype, NULL) != 0 || sshbuf_get_string(b, &sigblob, &len) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (strcmp("ssh-dss", ktype) != 0) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (sshbuf_len(b) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } } if (len != SIGBLOB_LEN) { ret = SSH_ERR_INVALID_FORMAT; goto out; } /* parse signature */ if ((sig = DSA_SIG_new()) == NULL || (sig->r = BN_new()) == NULL || (sig->s = BN_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } /* sha1 the data */ if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, digest, sizeof(digest))) != 0) goto out; switch (DSA_do_verify(digest, dlen, sig, key->dsa)) { case 1: ret = 0; break; case 0: ret = SSH_ERR_SIGNATURE_INVALID; goto out; default: ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } out: explicit_bzero(digest, sizeof(digest)); if (sig != NULL) DSA_SIG_free(sig); sshbuf_free(b); free(ktype); if (sigblob != NULL) { explicit_bzero(sigblob, len); free(sigblob); } return ret; } #endif /* WITH_OPENSSL */ openssh-7.2p2/ssh-ecdsa.c010064400017500001750000000122201267006270000134650ustar00djmdjm/* $OpenBSD: ssh-ecdsa.c,v 1.12 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 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" #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include #include #include #include #include #include #include "sshbuf.h" #include "ssherr.h" #include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" /* ARGSUSED */ int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t len, dlen; struct sshbuf *b = NULL, *bb = NULL; int ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || (dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) goto out; if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || (ret = sshbuf_put_stringb(b, bb)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sshbuf_ptr(b), len); } if (lenp != NULL) *lenp = len; ret = 0; out: explicit_bzero(digest, sizeof(digest)); sshbuf_free(b); sshbuf_free(bb); if (sig != NULL) ECDSA_SIG_free(sig); return ret; } /* ARGSUSED */ int ssh_ecdsa_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t dlen; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; char *ktype = NULL; if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || (dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ if ((b = sshbuf_from(signature, signaturelen)) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_get_cstring(b, &ktype, NULL) != 0 || sshbuf_froms(b, &sigbuf) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (sshbuf_len(b) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } /* parse signature */ if ((sig = ECDSA_SIG_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || sshbuf_get_bignum2(sigbuf, sig->s) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(sigbuf) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) { case 1: ret = 0; break; case 0: ret = SSH_ERR_SIGNATURE_INVALID; goto out; default: ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } out: explicit_bzero(digest, sizeof(digest)); sshbuf_free(sigbuf); sshbuf_free(b); if (sig != NULL) ECDSA_SIG_free(sig); free(ktype); return ret; } #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ openssh-7.2p2/ssh-ed25519.c010064400017500001750000000102551267006270000134120ustar00djmdjm/* $OpenBSD: ssh-ed25519.c,v 1.6 2015/01/15 21:38:50 markus Exp $ */ /* * Copyright (c) 2013 Markus Friedl * * 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 #include #include "crypto_api.h" #include #include #include "log.h" #include "sshbuf.h" #define SSHKEY_INTERNAL #include "sshkey.h" #include "ssherr.h" #include "ssh.h" int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { u_char *sig = NULL; size_t slen = 0, len; unsigned long long smlen; int r, ret; struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; if (key == NULL || sshkey_type_plain(key->type) != KEY_ED25519 || key->ed25519_sk == NULL || datalen >= INT_MAX - crypto_sign_ed25519_BYTES) return SSH_ERR_INVALID_ARGUMENT; smlen = slen = datalen + crypto_sign_ed25519_BYTES; if ((sig = malloc(slen)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, key->ed25519_sk)) != 0 || smlen <= datalen) { r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */ goto out; } /* encode signature */ if ((b = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_put_cstring(b, "ssh-ed25519")) != 0 || (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sshbuf_ptr(b), len); } if (lenp != NULL) *lenp = len; /* success */ r = 0; out: sshbuf_free(b); if (sig != NULL) { explicit_bzero(sig, slen); free(sig); } return r; } int ssh_ed25519_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat) { struct sshbuf *b = NULL; char *ktype = NULL; const u_char *sigblob; u_char *sm = NULL, *m = NULL; size_t len; unsigned long long smlen = 0, mlen = 0; int r, ret; if (key == NULL || sshkey_type_plain(key->type) != KEY_ED25519 || key->ed25519_pk == NULL || datalen >= INT_MAX - crypto_sign_ed25519_BYTES) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_from(signature, signaturelen)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 || (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0) goto out; if (strcmp("ssh-ed25519", ktype) != 0) { r = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (sshbuf_len(b) != 0) { r = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } if (len > crypto_sign_ed25519_BYTES) { r = SSH_ERR_INVALID_FORMAT; goto out; } if (datalen >= SIZE_MAX - len) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } smlen = len + datalen; mlen = smlen; if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(sm, sigblob, len); memcpy(sm+len, data, datalen); if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen, key->ed25519_pk)) != 0) { debug2("%s: crypto_sign_ed25519_open failed: %d", __func__, ret); } if (ret != 0 || mlen != datalen) { r = SSH_ERR_SIGNATURE_INVALID; goto out; } /* XXX compare 'm' and 'data' ? */ /* success */ r = 0; out: if (sm != NULL) { explicit_bzero(sm, smlen); free(sm); } if (m != NULL) { explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */ free(m); } sshbuf_free(b); free(ktype); return r; } openssh-7.2p2/ssh-gss.h010064400017500001750000000110671267006270000132170ustar00djmdjm/* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm 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. */ #ifndef _SSH_GSS_H #define _SSH_GSS_H #ifdef GSSAPI #ifdef HAVE_GSSAPI_H #include #elif defined(HAVE_GSSAPI_GSSAPI_H) #include #endif #ifdef KRB5 # ifndef HEIMDAL # ifdef HAVE_GSSAPI_GENERIC_H # include # elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) # include # endif /* Old MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */ # if !HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE # define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name # endif /* !HAVE_DECL_GSS_C_NT_... */ # endif /* !HEIMDAL */ #endif /* KRB5 */ /* draft-ietf-secsh-gsskeyex-06 */ #define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 #define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 #define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 #define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 #define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 #define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 #define SSH_GSS_OIDTYPE 0x06 typedef struct { char *filename; char *envvar; char *envval; void *data; } ssh_gssapi_ccache; typedef struct { gss_buffer_desc displayname; gss_buffer_desc exportedname; gss_cred_id_t creds; struct ssh_gssapi_mech_struct *mech; ssh_gssapi_ccache store; } ssh_gssapi_client; typedef struct ssh_gssapi_mech_struct { char *enc_name; char *name; gss_OID_desc oid; int (*dochild) (ssh_gssapi_client *); int (*userok) (ssh_gssapi_client *, char *); int (*localname) (ssh_gssapi_client *, char **); void (*storecreds) (ssh_gssapi_client *); } ssh_gssapi_mech; typedef struct { OM_uint32 major; /* both */ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ gss_OID oid; /* client */ gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* server */ } Gssctxt; extern ssh_gssapi_mech *supported_mechs[]; int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid(Gssctxt *, gss_OID); void ssh_gssapi_supported_oids(gss_OID_set *); ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); void ssh_gssapi_prepare_supported_oids(void); OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); OM_uint32 ssh_gssapi_getclient(Gssctxt *, ssh_gssapi_client *); void ssh_gssapi_error(Gssctxt *); char *ssh_gssapi_last_error(Gssctxt *, OM_uint32 *, OM_uint32 *); void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); /* In the server */ OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); int ssh_gssapi_userok(char *name); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); void ssh_gssapi_storecreds(void); #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ openssh-7.2p2/ssh-keygen.1010064400017500001750000000637441267006270000136270ustar00djmdjm.\" $OpenBSD: ssh-keygen.1,v 1.130 2016/02/17 07:38:19 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd $Mdocdate: February 17 2016 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME .Nm ssh-keygen .Nd authentication key generation, management and conversion .Sh SYNOPSIS .Bk -words .Nm ssh-keygen .Op Fl q .Op Fl b Ar bits .Op Fl t Cm dsa | ecdsa | ed25519 | rsa | rsa1 .Op Fl N Ar new_passphrase .Op Fl C Ar comment .Op Fl f Ar output_keyfile .Nm ssh-keygen .Fl p .Op Fl P Ar old_passphrase .Op Fl N Ar new_passphrase .Op Fl f Ar keyfile .Nm ssh-keygen .Fl i .Op Fl m Ar key_format .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl e .Op Fl m Ar key_format .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl y .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl c .Op Fl P Ar passphrase .Op Fl C Ar comment .Op Fl f Ar keyfile .Nm ssh-keygen .Fl l .Op Fl v .Op Fl E Ar fingerprint_hash .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl B .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl D Ar pkcs11 .Nm ssh-keygen .Fl F Ar hostname .Op Fl f Ar known_hosts_file .Op Fl l .Nm ssh-keygen .Fl H .Op Fl f Ar known_hosts_file .Nm ssh-keygen .Fl R Ar hostname .Op Fl f Ar known_hosts_file .Nm ssh-keygen .Fl r Ar hostname .Op Fl f Ar input_keyfile .Op Fl g .Nm ssh-keygen .Fl G Ar output_file .Op Fl v .Op Fl b Ar bits .Op Fl M Ar memory .Op Fl S Ar start_point .Nm ssh-keygen .Fl T Ar output_file .Fl f Ar input_file .Op Fl v .Op Fl a Ar rounds .Op Fl J Ar num_lines .Op Fl j Ar start_line .Op Fl K Ar checkpt .Op Fl W Ar generator .Nm ssh-keygen .Fl s Ar ca_key .Fl I Ar certificate_identity .Op Fl h .Op Fl n Ar principals .Op Fl O Ar option .Op Fl V Ar validity_interval .Op Fl z Ar serial_number .Ar .Nm ssh-keygen .Fl L .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl A .Nm ssh-keygen .Fl k .Fl f Ar krl_file .Op Fl u .Op Fl s Ar ca_public .Op Fl z Ar version_number .Ar .Nm ssh-keygen .Fl Q .Fl f Ar krl_file .Ar .Ek .Sh DESCRIPTION .Nm generates, manages and converts authentication keys for .Xr ssh 1 . .Nm can create keys for use by SSH protocol versions 1 and 2. Protocol 1 should not be used and is only offered to support legacy devices. It suffers from a number of cryptographic weaknesses and doesn't support many of the advanced features available for protocol 2. .Pp The type of key to be generated is specified with the .Fl t option. If invoked without any arguments, .Nm will generate an RSA key for use in SSH protocol 2 connections. .Pp .Nm is also used to generate groups for use in Diffie-Hellman group exchange (DH-GEX). See the .Sx MODULI GENERATION section for details. .Pp Finally, .Nm can be used to generate and update Key Revocation Lists, and to test whether given keys have been revoked by one. See the .Sx KEY REVOCATION LISTS section for details. .Pp Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in .Pa ~/.ssh/identity , .Pa ~/.ssh/id_dsa , .Pa ~/.ssh/id_ecdsa , .Pa ~/.ssh/id_ed25519 or .Pa ~/.ssh/id_rsa . Additionally, the system administrator may use this to generate host keys, as seen in .Pa /etc/rc . .Pp Normally this program generates the key and asks for a file in which to store the private key. The public key is stored in a file with the same name but .Dq .pub appended. The program also asks for a passphrase. The passphrase may be empty to indicate no passphrase (host keys must have an empty passphrase), or it may be a string of arbitrary length. A passphrase is similar to a password, except it can be a phrase with a series of words, punctuation, numbers, whitespace, or any string of characters you want. Good passphrases are 10-30 characters long, are not simple sentences or otherwise easily guessable (English prose has only 1-2 bits of entropy per character, and provides very bad passphrases), and contain a mix of upper and lowercase letters, numbers, and non-alphanumeric characters. The passphrase can be changed later by using the .Fl p option. .Pp There is no way to recover a lost passphrase. If the passphrase is lost or forgotten, a new key must be generated and the corresponding public key copied to other machines. .Pp For RSA1 keys, there is also a comment field in the key file that is only for convenience to the user to help identify the key. The comment can tell what the key is for, or whatever is useful. The comment is initialized to .Dq user@host when the key is created, but can be changed using the .Fl c option. .Pp After a key is generated, instructions below detail where the keys should be placed to be activated. .Pp The options are as follows: .Bl -tag -width Ds .It Fl A For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for which host keys do not exist, generate the host keys with the default key file path, an empty passphrase, default bits for the key type, and default comment. This is used by .Pa /etc/rc to generate new host keys. .It Fl a Ar rounds When saving a new-format private key (i.e. an ed25519 key or any SSH protocol 2 key when the .Fl o flag is set), this option specifies the number of KDF (key derivation function) rounds used. Higher numbers result in slower passphrase verification and increased resistance to brute-force password cracking (should the keys be stolen). .Pp When screening DH-GEX candidates ( using the .Fl T command). This option specifies the number of primality tests to perform. .It Fl B Show the bubblebabble digest of specified private or public key file. .It Fl b Ar bits Specifies the number of bits in the key to create. For RSA keys, the minimum size is 1024 bits and the default is 2048 bits. Generally, 2048 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, the .Fl b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. Ed25519 keys have a fixed length and the .Fl b flag will be ignored. .It Fl C Ar comment Provides a new comment. .It Fl c Requests changing the comment in the private and public key files. This operation is only supported for RSA1 keys. The program will prompt for the file containing the private keys, for the passphrase if the key has one, and for the new comment. .It Fl D Ar pkcs11 Download the RSA public keys provided by the PKCS#11 shared library .Ar pkcs11 . When used in combination with .Fl s , this option indicates that a CA key resides in a PKCS#11 token (see the .Sx CERTIFICATES section for details). .It Fl E Ar fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: .Dq md5 and .Dq sha256 . The default is .Dq sha256 . .It Fl e This option will read a private or public OpenSSH key file and print to stdout the key in one of the formats specified by the .Fl m option. The default export format is .Dq RFC4716 . This option allows exporting OpenSSH keys for use by other programs, including several commercial SSH implementations. .It Fl F Ar hostname Search for the specified .Ar hostname in a .Pa known_hosts file, listing any occurrences found. This option is useful to find hashed host names or addresses and may also be used in conjunction with the .Fl H option to print found keys in a hashed format. .It Fl f Ar filename Specifies the filename of the key file. .It Fl G Ar output_file Generate candidate primes for DH-GEX. These primes must be screened for safety (using the .Fl T option) before use. .It Fl g Use generic DNS format when printing fingerprint resource records using the .Fl r command. .It Fl H Hash a .Pa known_hosts file. This replaces all hostnames and addresses with hashed representations within the specified file; the original content is moved to a file with a .old suffix. These hashes may be used normally by .Nm ssh and .Nm sshd , but they do not reveal identifying information should the file's contents be disclosed. This option will not modify existing hashed hostnames and is therefore safe to use on files that mix hashed and non-hashed names. .It Fl h When signing a key, create a host certificate instead of a user certificate. Please see the .Sx CERTIFICATES section for details. .It Fl I Ar certificate_identity Specify the key identity when signing a public key. Please see the .Sx CERTIFICATES section for details. .It Fl i This option will read an unencrypted private (or public) key file in the format specified by the .Fl m option and print an OpenSSH compatible private (or public) key to stdout. This option allows importing keys from other software, including several commercial SSH implementations. The default import format is .Dq RFC4716 . .It Fl J Ar num_lines Exit after screening the specified number of lines while performing DH candidate screening using the .Fl T option. .It Fl j Ar start_line Start screening at the specified line number while performing DH candidate screening using the .Fl T option. .It Fl K Ar checkpt Write the last line processed to the file .Ar checkpt while performing DH candidate screening using the .Fl T option. This will be used to skip lines in the input file that have already been processed if the job is restarted. .It Fl k Generate a KRL file. In this mode, .Nm will generate a KRL file at the location specified via the .Fl f flag that revokes every key or certificate presented on the command line. Keys/certificates to be revoked may be specified by public key file or using the format described in the .Sx KEY REVOCATION LISTS section. .It Fl L Prints the contents of one or more certificates. .It Fl l Show fingerprint of specified public key file. Private RSA1 keys are also supported. For RSA and DSA keys .Nm tries to find the matching public key file and prints its fingerprint. If combined with .Fl v , an ASCII art representation of the key is supplied with the fingerprint. .It Fl M Ar memory Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX. .It Fl m Ar key_format Specify a key format for the .Fl i (import) or .Fl e (export) conversion options. The supported key formats are: .Dq RFC4716 (RFC 4716/SSH2 public or private key), .Dq PKCS8 (PEM PKCS8 public key) or .Dq PEM (PEM public key). The default conversion format is .Dq RFC4716 . .It Fl N Ar new_passphrase Provides the new passphrase. .It Fl n Ar principals Specify one or more principals (user or host names) to be included in a certificate when signing a key. Multiple principals may be specified, separated by commas. Please see the .Sx CERTIFICATES section for details. .It Fl O Ar option Specify a certificate option when signing a key. This option may be specified multiple times. Please see the .Sx CERTIFICATES section for details. The options that are valid for user certificates are: .Bl -tag -width Ds .It Ic clear Clear all enabled permissions. This is useful for clearing the default set of permissions so permissions may be added individually. .It Ic force-command Ns = Ns Ar command Forces the execution of .Ar command instead of any shell or command specified by the user when the certificate is used for authentication. .It Ic no-agent-forwarding Disable .Xr ssh-agent 1 forwarding (permitted by default). .It Ic no-port-forwarding Disable port forwarding (permitted by default). .It Ic no-pty Disable PTY allocation (permitted by default). .It Ic no-user-rc Disable execution of .Pa ~/.ssh/rc by .Xr sshd 8 (permitted by default). .It Ic no-x11-forwarding Disable X11 forwarding (permitted by default). .It Ic permit-agent-forwarding Allows .Xr ssh-agent 1 forwarding. .It Ic permit-port-forwarding Allows port forwarding. .It Ic permit-pty Allows PTY allocation. .It Ic permit-user-rc Allows execution of .Pa ~/.ssh/rc by .Xr sshd 8 . .It Ic permit-x11-forwarding Allows X11 forwarding. .It Ic source-address Ns = Ns Ar address_list Restrict the source addresses from which the certificate is considered valid. The .Ar address_list is a comma-separated list of one or more address/netmask pairs in CIDR format. .El .Pp At present, no options are valid for host keys. .It Fl o Causes .Nm to save private keys using the new OpenSSH format rather than the more compatible PEM format. The new format has increased resistance to brute-force password cracking but is not supported by versions of OpenSSH prior to 6.5. Ed25519 keys always use the new private key format. .It Fl P Ar passphrase Provides the (old) passphrase. .It Fl p Requests changing the passphrase of a private key file instead of creating a new private key. The program will prompt for the file containing the private key, for the old passphrase, and twice for the new passphrase. .It Fl Q Test whether keys have been revoked in a KRL. .It Fl q Silence .Nm ssh-keygen . .It Fl R Ar hostname Removes all keys belonging to .Ar hostname from a .Pa known_hosts file. This option is useful to delete hashed hosts (see the .Fl H option above). .It Fl r Ar hostname Print the SSHFP fingerprint resource record named .Ar hostname for the specified public key file. .It Fl S Ar start Specify start point (in hex) when generating candidate moduli for DH-GEX. .It Fl s Ar ca_key Certify (sign) a public key using the specified CA key. Please see the .Sx CERTIFICATES section for details. .Pp When generating a KRL, .Fl s specifies a path to a CA public key file used to revoke certificates directly by key ID or serial number. See the .Sx KEY REVOCATION LISTS section for details. .It Fl T Ar output_file Test DH group exchange candidate primes (generated using the .Fl G option) for safety. .It Fl t Cm dsa | ecdsa | ed25519 | rsa | rsa1 Specifies the type of key to create. The possible values are .Dq rsa1 for protocol version 1 and .Dq dsa , .Dq ecdsa , .Dq ed25519 , or .Dq rsa for protocol version 2. .It Fl u Update a KRL. When specified with .Fl k , keys listed via the command line are added to the existing KRL rather than a new KRL being created. .It Fl V Ar validity_interval Specify a validity interval when signing a certificate. A validity interval may consist of a single time, indicating that the certificate is valid beginning now and expiring at that time, or may consist of two times separated by a colon to indicate an explicit time interval. The start time may be specified as a date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting of a minus sign followed by a relative time in the format described in the TIME FORMATS section of .Xr sshd_config 5 . The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time starting with a plus character. .Pp For example: .Dq +52w1d (valid from now to 52 weeks and one day from now), .Dq -4w:+4w (valid from four weeks ago to four weeks from now), .Dq 20100101123000:20110101123000 (valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011), .Dq -1d:20110101 (valid from yesterday to midnight, January 1st, 2011). .It Fl v Verbose mode. Causes .Nm to print debugging messages about its progress. This is helpful for debugging moduli generation. Multiple .Fl v options increase the verbosity. The maximum is 3. .It Fl W Ar generator Specify desired generator when testing candidate moduli for DH-GEX. .It Fl y This option will read a private OpenSSH format file and print an OpenSSH public key to stdout. .It Fl z Ar serial_number Specifies a serial number to be embedded in the certificate to distinguish this certificate from others from the same CA. The default serial number is zero. .Pp When generating a KRL, the .Fl z flag is used to specify a KRL version number. .El .Sh MODULI GENERATION .Nm may be used to generate groups for the Diffie-Hellman Group Exchange (DH-GEX) protocol. Generating these groups is a two-step process: first, candidate primes are generated using a fast, but memory intensive process. These candidate primes are then tested for suitability (a CPU-intensive process). .Pp Generation of primes is performed using the .Fl G option. The desired length of the primes may be specified by the .Fl b option. For example: .Pp .Dl # ssh-keygen -G moduli-2048.candidates -b 2048 .Pp By default, the search for primes begins at a random point in the desired length range. This may be overridden using the .Fl S option, which specifies a different start point (in hex). .Pp Once a set of candidates have been generated, they must be screened for suitability. This may be performed using the .Fl T option. In this mode .Nm will read candidates from standard input (or a file specified using the .Fl f option). For example: .Pp .Dl # ssh-keygen -T moduli-2048 -f moduli-2048.candidates .Pp By default, each candidate will be subjected to 100 primality tests. This may be overridden using the .Fl a option. The DH generator value will be chosen automatically for the prime under consideration. If a specific generator is desired, it may be requested using the .Fl W option. Valid generator values are 2, 3, and 5. .Pp Screened DH groups may be installed in .Pa /etc/moduli . It is important that this file contains moduli of a range of bit lengths and that both ends of a connection share common moduli. .Sh CERTIFICATES .Nm supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in .Xr ssl 8 . .Pp .Nm supports two types of certificates: user and host. User certificates authenticate users to servers, whereas host certificates authenticate server hosts to users. To generate a user certificate: .Pp .Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub .Pp The resultant certificate will be placed in .Pa /path/to/user_key-cert.pub . A host certificate requires the .Fl h option: .Pp .Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub .Pp The host certificate will be output to .Pa /path/to/host_key-cert.pub . .Pp It is possible to sign using a CA key stored in a PKCS#11 token by providing the token library using .Fl D and identifying the CA key by providing its public half as an argument to .Fl s : .Pp .Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub .Pp In all cases, .Ar key_id is a "key identifier" that is logged by the server when the certificate is used for authentication. .Pp Certificates may be limited to be valid for a set of principal (user/host) names. By default, generated certificates are valid for all users or hosts. To generate a certificate for a specified set of principals: .Pp .Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub .Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub" .Pp Additional limitations on the validity and use of user certificates may be specified through certificate options. A certificate option may disable features of the SSH session, may be valid only when presented from particular source addresses or may force the use of a specific command. For a list of valid certificate options, see the documentation for the .Fl O option above. .Pp Finally, certificates may be defined with a validity lifetime. The .Fl V option allows specification of certificate start and end times. A certificate that is presented at a time outside this range will not be considered valid. By default, certificates are valid from .Ux Epoch to the distant future. .Pp For certificates to be used for user or host authentication, the CA public key must be trusted by .Xr sshd 8 or .Xr ssh 1 . Please refer to those manual pages for details. .Sh KEY REVOCATION LISTS .Nm is able to manage OpenSSH format Key Revocation Lists (KRLs). These binary files specify keys or certificates to be revoked using a compact format, taking as little as one bit per certificate if they are being revoked by serial number. .Pp KRLs may be generated using the .Fl k flag. This option reads one or more files from the command line and generates a new KRL. The files may either contain a KRL specification (see below) or public keys, listed one per line. Plain public keys are revoked by listing their hash or contents in the KRL and certificates revoked by serial number or key ID (if the serial is zero or not available). .Pp Revoking keys using a KRL specification offers explicit control over the types of record used to revoke keys and may be used to directly revoke certificates by serial number or key ID without having the complete original certificate on hand. A KRL specification consists of lines containing one of the following directives followed by a colon and some directive-specific information. .Bl -tag -width Ds .It Cm serial : Ar serial_number Ns Op - Ns Ar serial_number Revokes a certificate with the specified serial number. Serial numbers are 64-bit values, not including zero and may be expressed in decimal, hex or octal. If two serial numbers are specified separated by a hyphen, then the range of serial numbers including and between each is revoked. The CA key must have been specified on the .Nm command line using the .Fl s option. .It Cm id : Ar key_id Revokes a certificate with the specified key ID string. The CA key must have been specified on the .Nm command line using the .Fl s option. .It Cm key : Ar public_key Revokes the specified key. If a certificate is listed, then it is revoked as a plain public key. .It Cm sha1 : Ar public_key Revokes the specified key by its SHA1 hash. .El .Pp KRLs may be updated using the .Fl u flag in addition to .Fl k . When this option is specified, keys listed via the command line are merged into the KRL, adding to those already there. .Pp It is also possible, given a KRL, to test whether it revokes a particular key (or keys). The .Fl Q flag will query an existing KRL, testing each key specified on the command line. If any key listed on the command line has been revoked (or an error encountered) then .Nm will exit with a non-zero exit status. A zero exit status will only be returned if no key was revoked. .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt the private part of this file using 3DES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. .Xr ssh 1 will read this file when a login attempt is made. .Pp .It Pa ~/.ssh/identity.pub Contains the protocol version 1 RSA public key for authentication. The contents of this file should be added to .Pa ~/.ssh/authorized_keys on all machines where the user wishes to log in using RSA authentication. There is no need to keep the contents of this file secret. .Pp .It Pa ~/.ssh/id_dsa .It Pa ~/.ssh/id_ecdsa .It Pa ~/.ssh/id_ed25519 .It Pa ~/.ssh/id_rsa Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt the private part of this file using 128-bit AES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. .Xr ssh 1 will read this file when a login attempt is made. .Pp .It Pa ~/.ssh/id_dsa.pub .It Pa ~/.ssh/id_ecdsa.pub .It Pa ~/.ssh/id_ed25519.pub .It Pa ~/.ssh/id_rsa.pub Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public key for authentication. The contents of this file should be added to .Pa ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. .Pp .It Pa /etc/moduli Contains Diffie-Hellman groups used for DH-GEX. The file format is described in .Xr moduli 5 . .El .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr moduli 5 , .Xr sshd 8 .Rs .%R RFC 4716 .%T "The Secure Shell (SSH) Public Key File Format" .%D 2006 .Re .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.2p2/ssh-keygen.c010064400017500001750000002202761267006270000137040ustar00djmdjm/* $OpenBSD: ssh-keygen.c,v 1.288 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland * All rights reserved * Identity and host key generation and maintenance. * * 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 #include #include #ifdef WITH_OPENSSL #include #include #include "openbsd-compat/openssl-compat.h" #endif #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #include #include #include #include "xmalloc.h" #include "sshkey.h" #include "rsa.h" #include "authfile.h" #include "uuencode.h" #include "sshbuf.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "match.h" #include "hostfile.h" #include "dns.h" #include "ssh.h" #include "ssh2.h" #include "ssherr.h" #include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" #include "digest.h" #ifdef WITH_OPENSSL # define DEFAULT_KEY_TYPE_NAME "rsa" #else # define DEFAULT_KEY_TYPE_NAME "ed25519" #endif /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ #define DEFAULT_BITS 2048 #define DEFAULT_BITS_DSA 1024 #define DEFAULT_BITS_ECDSA 256 u_int32_t bits = 0; /* * Flag indicating that we just want to change the passphrase. This can be * set on the command line. */ int change_passphrase = 0; /* * Flag indicating that we just want to change the comment. This can be set * on the command line. */ int change_comment = 0; int quiet = 0; int log_level = SYSLOG_LEVEL_INFO; /* Flag indicating that we want to hash a known_hosts file */ int hash_hosts = 0; /* Flag indicating that we want lookup a host in known_hosts file */ int find_host = 0; /* Flag indicating that we want to delete a host from a known_hosts file */ int delete_host = 0; /* Flag indicating that we want to show the contents of a certificate */ int show_cert = 0; /* Flag indicating that we just want to see the key fingerprint */ int print_fingerprint = 0; int print_bubblebabble = 0; /* Hash algorithm to use for fingerprints. */ int fingerprint_hash = SSH_FP_HASH_DEFAULT; /* The identity file name, given on the command line or entered by the user. */ char identity_file[1024]; int have_identity = 0; /* This is set to the passphrase if given on the command line. */ char *identity_passphrase = NULL; /* This is set to the new passphrase if given on the command line. */ char *identity_new_passphrase = NULL; /* This is set to the new comment if given on the command line. */ char *identity_comment = NULL; /* Path to CA key when certifying keys. */ char *ca_key_path = NULL; /* Certificate serial number */ unsigned long long cert_serial = 0; /* Key type when certifying */ u_int cert_key_type = SSH2_CERT_TYPE_USER; /* "key ID" of signed key */ char *cert_key_id = NULL; /* Comma-separated list of principal names for certifying keys */ char *cert_principals = NULL; /* Validity period for certificates */ u_int64_t cert_valid_from = 0; u_int64_t cert_valid_to = ~0ULL; /* Certificate options */ #define CERTOPT_X_FWD (1) #define CERTOPT_AGENT_FWD (1<<1) #define CERTOPT_PORT_FWD (1<<2) #define CERTOPT_PTY (1<<3) #define CERTOPT_USER_RC (1<<4) #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) u_int32_t certflags_flags = CERTOPT_DEFAULT; char *certflags_command = NULL; char *certflags_src_addr = NULL; /* Conversion to/from various formats */ int convert_to = 0; int convert_from = 0; enum { FMT_RFC4716, FMT_PKCS8, FMT_PEM } convert_format = FMT_RFC4716; int print_public = 0; int print_generic = 0; char *key_type_name = NULL; /* Load key from this PKCS#11 provider */ char *pkcs11provider = NULL; /* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ int use_new_format = 0; /* Cipher for new-format private keys */ char *new_format_cipher = NULL; /* * Number of KDF rounds to derive new format keys / * number of primality trials when screening moduli. */ int rounds = 0; /* argv0 */ extern char *__progname; char hostname[NI_MAXHOST]; #ifdef WITH_OPENSSL /* moduli.c */ int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); #endif static void type_bits_valid(int type, const char *name, u_int32_t *bitsp) { #ifdef WITH_OPENSSL u_int maxbits, nid; #endif if (type == KEY_UNSPEC) fatal("unknown key type %s", key_type_name); if (*bitsp == 0) { #ifdef WITH_OPENSSL if (type == KEY_DSA) *bitsp = DEFAULT_BITS_DSA; else if (type == KEY_ECDSA) { if (name != NULL && (nid = sshkey_ecdsa_nid_from_name(name)) > 0) *bitsp = sshkey_curve_nid_to_bits(nid); if (*bitsp == 0) *bitsp = DEFAULT_BITS_ECDSA; } else #endif *bitsp = DEFAULT_BITS; } #ifdef WITH_OPENSSL maxbits = (type == KEY_DSA) ? OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (*bitsp > maxbits) fatal("key bits exceeds maximum %d", maxbits); if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) fatal("Key must at least be 1024 bits"); else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) fatal("Invalid ECDSA key length - valid lengths are " "256, 384 or 521 bits"); #endif } static void ask_filename(struct passwd *pw, const char *prompt) { char buf[1024]; char *name = NULL; if (key_type_name == NULL) name = _PATH_SSH_CLIENT_ID_RSA; else { switch (sshkey_type_from_name(key_type_name)) { case KEY_RSA1: name = _PATH_SSH_CLIENT_IDENTITY; break; case KEY_DSA_CERT: case KEY_DSA: name = _PATH_SSH_CLIENT_ID_DSA; break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: name = _PATH_SSH_CLIENT_ID_ECDSA; break; #endif case KEY_RSA_CERT: case KEY_RSA: name = _PATH_SSH_CLIENT_ID_RSA; break; case KEY_ED25519: case KEY_ED25519_CERT: name = _PATH_SSH_CLIENT_ID_ED25519; break; default: fatal("bad key type"); } } snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); printf("%s (%s): ", prompt, identity_file); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) exit(1); buf[strcspn(buf, "\n")] = '\0'; if (strcmp(buf, "") != 0) strlcpy(identity_file, buf, sizeof(identity_file)); have_identity = 1; } static struct sshkey * load_identity(char *filename) { char *pass; struct sshkey *prv; int r; if ((r = sshkey_load_private(filename, "", &prv, NULL)) == 0) return prv; if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) fatal("Load key \"%s\": %s", filename, ssh_err(r)); if (identity_passphrase) pass = xstrdup(identity_passphrase); else pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); r = sshkey_load_private(filename, pass, &prv, NULL); explicit_bzero(pass, strlen(pass)); free(pass); if (r != 0) fatal("Load key \"%s\": %s", filename, ssh_err(r)); return prv; } #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb #ifdef WITH_OPENSSL static void do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) { size_t len; u_char *blob; char comment[61]; int r; if (k->type == KEY_RSA1) fatal("version 1 keys are not supported"); if ((r = sshkey_to_blob(k, &blob, &len)) != 0) fatal("key_to_blob failed: %s", ssh_err(r)); /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ snprintf(comment, sizeof(comment), "%u-bit %s, converted by %s@%s from OpenSSH", sshkey_size(k), sshkey_type(k), pw->pw_name, hostname); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); fprintf(stdout, "Comment: \"%s\"\n", comment); dump_base64(stdout, blob, len); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); sshkey_free(k); free(blob); exit(0); } static void do_convert_to_pkcs8(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) fatal("PEM_write_RSA_PUBKEY failed"); break; case KEY_DSA: if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) fatal("PEM_write_DSA_PUBKEY failed"); break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) fatal("PEM_write_EC_PUBKEY failed"); break; #endif default: fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } static void do_convert_to_pem(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSAPublicKey(stdout, k->rsa)) fatal("PEM_write_RSAPublicKey failed"); break; #if notyet /* OpenSSH 0.9.8 lacks this function */ case KEY_DSA: if (!PEM_write_DSAPublicKey(stdout, k->dsa)) fatal("PEM_write_DSAPublicKey failed"); break; #endif /* XXX ECDSA? */ default: fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } static void do_convert_to(struct passwd *pw) { struct sshkey *k; struct stat st; int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0) k = load_identity(identity_file); switch (convert_format) { case FMT_RFC4716: do_convert_to_ssh2(pw, k); break; case FMT_PKCS8: do_convert_to_pkcs8(k); break; case FMT_PEM: do_convert_to_pem(k); break; default: fatal("%s: unknown key format %d", __func__, convert_format); } exit(0); } /* * This is almost exactly the bignum1 encoding, but with 32 bit for length * instead of 16. */ static void buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value) { u_int bytes, bignum_bits; int r; if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); bytes = (bignum_bits + 7) / 8; if (sshbuf_len(b) < bytes) fatal("%s: input buffer too small: need %d have %zu", __func__, bytes, sshbuf_len(b)); if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL) fatal("%s: BN_bin2bn failed", __func__); if ((r = sshbuf_consume(b, bytes)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } static struct sshkey * do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) { struct sshbuf *b; struct sshkey *key = NULL; char *type, *cipher; u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; int r, rlen, ktype; u_int magic, i1, i2, i3, i4; size_t slen; u_long e; if ((b = sshbuf_from(blob, blen)) == NULL) fatal("%s: sshbuf_from failed", __func__); if ((r = sshbuf_get_u32(b, &magic)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); sshbuf_free(b); return NULL; } if ((r = sshbuf_get_u32(b, &i1)) != 0 || (r = sshbuf_get_cstring(b, &type, NULL)) != 0 || (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 || (r = sshbuf_get_u32(b, &i2)) != 0 || (r = sshbuf_get_u32(b, &i3)) != 0 || (r = sshbuf_get_u32(b, &i4)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("ignore (%d %d %d %d)", i1, i2, i3, i4); if (strcmp(cipher, "none") != 0) { error("unsupported cipher %s", cipher); free(cipher); sshbuf_free(b); free(type); return NULL; } free(cipher); if (strstr(type, "dsa")) { ktype = KEY_DSA; } else if (strstr(type, "rsa")) { ktype = KEY_RSA; } else { sshbuf_free(b); free(type); return NULL; } if ((key = sshkey_new_private(ktype)) == NULL) fatal("key_new_private failed"); free(type); switch (key->type) { case KEY_DSA: buffer_get_bignum_bits(b, key->dsa->p); buffer_get_bignum_bits(b, key->dsa->g); buffer_get_bignum_bits(b, key->dsa->q); buffer_get_bignum_bits(b, key->dsa->pub_key); buffer_get_bignum_bits(b, key->dsa->priv_key); break; case KEY_RSA: if ((r = sshbuf_get_u8(b, &e1)) != 0 || (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) fatal("%s: buffer error: %s", __func__, ssh_err(r)); e = e1; debug("e %lx", e); if (e < 30) { e <<= 8; e += e2; debug("e %lx", e); e <<= 8; e += e3; debug("e %lx", e); } if (!BN_set_word(key->rsa->e, e)) { sshbuf_free(b); sshkey_free(key); return NULL; } buffer_get_bignum_bits(b, key->rsa->d); buffer_get_bignum_bits(b, key->rsa->n); buffer_get_bignum_bits(b, key->rsa->iqmp); buffer_get_bignum_bits(b, key->rsa->q); buffer_get_bignum_bits(b, key->rsa->p); if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) fatal("generate RSA parameters failed: %s", ssh_err(r)); break; } rlen = sshbuf_len(b); if (rlen != 0) error("do_convert_private_ssh2_from_blob: " "remaining bytes in key blob %d", rlen); sshbuf_free(b); /* try the key */ if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) { sshkey_free(key); free(sig); return NULL; } free(sig); return key; } static int get_line(FILE *fp, char *line, size_t len) { int c; size_t pos = 0; line[0] = '\0'; while ((c = fgetc(fp)) != EOF) { if (pos >= len - 1) fatal("input line too long."); switch (c) { case '\r': c = fgetc(fp); if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) fatal("unget: %s", strerror(errno)); return pos; case '\n': return pos; } line[pos++] = c; line[pos] = '\0'; } /* We reached EOF */ return -1; } static void do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private) { int r, blen, escaped = 0; u_int len; char line[1024]; u_char blob[8096]; char encoded[8096]; FILE *fp; if ((fp = fopen(identity_file, "r")) == NULL) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); encoded[0] = '\0'; while ((blen = get_line(fp, line, sizeof(line))) != -1) { if (blen > 0 && line[blen - 1] == '\\') escaped++; if (strncmp(line, "----", 4) == 0 || strstr(line, ": ") != NULL) { if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) *private = 1; if (strstr(line, " END ") != NULL) { break; } /* fprintf(stderr, "ignore: %s", line); */ continue; } if (escaped) { escaped--; /* fprintf(stderr, "escaped: %s", line); */ continue; } strlcat(encoded, line, sizeof(encoded)); } len = strlen(encoded); if (((len % 4) == 3) && (encoded[len-1] == '=') && (encoded[len-2] == '=') && (encoded[len-3] == '=')) encoded[len-3] = '\0'; blen = uudecode(encoded, blob, sizeof(blob)); if (blen < 0) fatal("uudecode failed."); if (*private) *k = do_convert_private_ssh2_from_blob(blob, blen); else if ((r = sshkey_from_blob(blob, blen, k)) != 0) fatal("decode blob failed: %s", ssh_err(r)); fclose(fp); } static void do_convert_from_pkcs8(struct sshkey **k, int *private) { EVP_PKEY *pubkey; FILE *fp; if ((fp = fopen(identity_file, "r")) == NULL) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { fatal("%s: %s is not a recognised public key format", __func__, identity_file); } fclose(fp); switch (EVP_PKEY_type(pubkey->type)) { case EVP_PKEY_RSA: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); break; case EVP_PKEY_DSA: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); break; #ifdef OPENSSL_HAS_ECC case EVP_PKEY_EC: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_ECDSA; (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); break; #endif default: fatal("%s: unsupported pubkey type %d", __func__, EVP_PKEY_type(pubkey->type)); } EVP_PKEY_free(pubkey); return; } static void do_convert_from_pem(struct sshkey **k, int *private) { FILE *fp; RSA *rsa; #ifdef notyet DSA *dsa; #endif if ((fp = fopen(identity_file, "r")) == NULL) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = rsa; fclose(fp); return; } #if notyet /* OpenSSH 0.9.8 lacks this function */ rewind(fp); if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = dsa; fclose(fp); return; } /* XXX ECDSA */ #endif fatal("%s: unrecognised raw private key format", __func__); } static void do_convert_from(struct passwd *pw) { struct sshkey *k = NULL; int r, private = 0, ok = 0; struct stat st; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); switch (convert_format) { case FMT_RFC4716: do_convert_from_ssh2(pw, &k, &private); break; case FMT_PKCS8: do_convert_from_pkcs8(&k, &private); break; case FMT_PEM: do_convert_from_pem(&k, &private); break; default: fatal("%s: unknown key format %d", __func__, convert_format); } if (!private) { if ((r = sshkey_write(k, stdout)) == 0) ok = 1; if (ok) fprintf(stdout, "\n"); } else { switch (k->type) { case KEY_DSA: ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL); break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, NULL, 0, NULL, NULL); break; #endif case KEY_RSA: ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL); break; default: fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } } if (!ok) fatal("key write failed"); sshkey_free(k); exit(0); } #endif static void do_print_public(struct passwd *pw) { struct sshkey *prv; struct stat st; int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s", identity_file, strerror(errno)); prv = load_identity(identity_file); if ((r = sshkey_write(prv, stdout)) != 0) error("key_write failed: %s", ssh_err(r)); sshkey_free(prv); fprintf(stdout, "\n"); exit(0); } static void do_download(struct passwd *pw) { #ifdef ENABLE_PKCS11 struct sshkey **keys = NULL; int i, nkeys; enum sshkey_fp_rep rep; int fptype; char *fp, *ra; fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; pkcs11_init(0); nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); if (nkeys <= 0) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { if (print_fingerprint) { fp = sshkey_fingerprint(keys[i], fptype, rep); ra = sshkey_fingerprint(keys[i], fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]), fp, sshkey_type(keys[i])); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ fprintf(stdout, "\n"); } sshkey_free(keys[i]); } free(keys); pkcs11_terminate(); exit(0); #else fatal("no pkcs11 support"); #endif /* ENABLE_PKCS11 */ } static struct sshkey * try_read_key(char **cpp) { struct sshkey *ret; int r; if ((ret = sshkey_new(KEY_RSA1)) == NULL) fatal("sshkey_new failed"); /* Try RSA1 */ if ((r = sshkey_read(ret, cpp)) == 0) return ret; /* Try modern */ sshkey_free(ret); if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); if ((r = sshkey_read(ret, cpp)) == 0) return ret; /* Not a key */ sshkey_free(ret); return NULL; } static void fingerprint_one_key(const struct sshkey *public, const char *comment) { char *fp = NULL, *ra = NULL; enum sshkey_fp_rep rep; int fptype; fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; fp = sshkey_fingerprint(public, fptype, rep); ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint failed", __func__); printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } static void fingerprint_private(const char *path) { struct stat st; char *comment = NULL; struct sshkey *public = NULL; int r; if (stat(identity_file, &st) < 0) fatal("%s: %s", path, strerror(errno)); if ((r = sshkey_load_public(path, &public, &comment)) != 0) { debug("load public \"%s\": %s", path, ssh_err(r)); if ((r = sshkey_load_private(path, NULL, &public, &comment)) != 0) { debug("load private \"%s\": %s", path, ssh_err(r)); fatal("%s is not a key file.", path); } } fingerprint_one_key(public, comment); sshkey_free(public); free(comment); } static void do_fingerprint(struct passwd *pw) { FILE *f; struct sshkey *public = NULL; char *comment = NULL, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; int i, invalid = 1; const char *path; long int lnum = 0; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); path = identity_file; if (strcmp(identity_file, "-") == 0) { f = stdin; path = "(stdin)"; } else if ((f = fopen(path, "r")) == NULL) fatal("%s: %s: %s", __progname, path, strerror(errno)); while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) { cp = line; cp[strcspn(cp, "\n")] = '\0'; /* Trim leading space and comments */ cp = line + strspn(line, " \t"); if (*cp == '#' || *cp == '\0') continue; /* * Input may be plain keys, private keys, authorized_keys * or known_hosts. */ /* * Try private keys first. Assume a key is private if * "SSH PRIVATE KEY" appears on the first line and we're * not reading from stdin (XXX support private keys on stdin). */ if (lnum == 1 && strcmp(identity_file, "-") != 0 && strstr(cp, "PRIVATE KEY") != NULL) { fclose(f); fingerprint_private(path); exit(0); } /* * If it's not a private key, then this must be prepared to * accept a public key prefixed with a hostname or options. * Try a bare key first, otherwise skip the leading stuff. */ if ((public = try_read_key(&cp)) == NULL) { i = strtol(cp, &ep, 10); if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { int quoted = 0; comment = cp; for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { if (*cp == '\\' && cp[1] == '"') cp++; /* Skip both */ else if (*cp == '"') quoted = !quoted; } if (!*cp) continue; *cp++ = '\0'; } } /* Retry after parsing leading hostname/key options */ if (public == NULL && (public = try_read_key(&cp)) == NULL) { debug("%s:%ld: not a public key", path, lnum); continue; } /* Find trailing comment, if any */ for (; *cp == ' ' || *cp == '\t'; cp++) ; if (*cp != '\0' && *cp != '#') comment = cp; fingerprint_one_key(public, comment); sshkey_free(public); invalid = 0; /* One good key in the file is sufficient */ } fclose(f); if (invalid) fatal("%s is not a public key file.", path); exit(0); } static void do_gen_all_hostkeys(struct passwd *pw) { struct { char *key_type; char *key_type_display; char *path; } key_types[] = { #ifdef WITH_OPENSSL #ifdef WITH_SSH1 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE }, #endif /* WITH_SSH1 */ { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, #ifdef OPENSSL_HAS_ECC { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, { NULL, NULL, NULL } }; int first = 0; struct stat st; struct sshkey *private, *public; char comment[1024]; int i, type, fd, r; FILE *f; for (i = 0; key_types[i].key_type; i++) { if (stat(key_types[i].path, &st) == 0) continue; if (errno != ENOENT) { error("Could not stat %s: %s", key_types[i].path, strerror(errno)); first = 0; continue; } if (first == 0) { first = 1; printf("%s: generating new host keys: ", __progname); } printf("%s ", key_types[i].key_type_display); fflush(stdout); type = sshkey_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; type_bits_valid(type, NULL, &bits); if ((r = sshkey_generate(type, bits, &private)) != 0) { error("key_generate failed: %s", ssh_err(r)); first = 0; continue; } if ((r = sshkey_from_private(private, &public)) != 0) fatal("sshkey_from_private failed: %s", ssh_err(r)); snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); if ((r = sshkey_save_private(private, identity_file, "", comment, use_new_format, new_format_cipher, rounds)) != 0) { error("Saving key \"%s\" failed: %s", identity_file, ssh_err(r)); sshkey_free(private); sshkey_free(public); first = 0; continue; } sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { error("Could not save your public key in %s", identity_file); sshkey_free(public); first = 0; continue; } f = fdopen(fd, "w"); if (f == NULL) { error("fdopen %s failed", identity_file); close(fd); sshkey_free(public); first = 0; continue; } if ((r = sshkey_write(public, f)) != 0) { error("write key failed: %s", ssh_err(r)); fclose(f); sshkey_free(public); first = 0; continue; } fprintf(f, " %s\n", comment); fclose(f); sshkey_free(public); } if (first != 0) printf("\n"); } struct known_hosts_ctx { const char *host; /* Hostname searched for in find/delete case */ FILE *out; /* Output file, stdout for find_hosts case */ int has_unhashed; /* When hashing, original had unhashed hosts */ int found_key; /* For find/delete, host was found */ int invalid; /* File contained invalid items; don't delete */ }; static int known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) { struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; char *hashed, *cp, *hosts, *ohosts; int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); switch (l->status) { case HKF_STATUS_OK: case HKF_STATUS_MATCHED: /* * Don't hash hosts already already hashed, with wildcard * characters or a CA/revocation marker. */ if ((l->match & HKF_MATCH_HOST_HASHED) != 0 || has_wild || l->marker != MRK_NONE) { fprintf(ctx->out, "%s\n", l->line); if (has_wild && !find_host) { logit("%s:%ld: ignoring host name " "with wildcard: %.64s", l->path, l->linenum, l->hosts); } return 0; } /* * Split any comma-separated hostnames from the host list, * hash and store separately. */ ohosts = hosts = xstrdup(l->hosts); while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { if ((hashed = host_hash(cp, NULL, 0)) == NULL) fatal("hash_host failed"); fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); ctx->has_unhashed = 1; } free(ohosts); return 0; case HKF_STATUS_INVALID: /* Retain invalid lines, but mark file as invalid. */ ctx->invalid = 1; logit("%s:%ld: invalid line", l->path, l->linenum); /* FALLTHROUGH */ default: fprintf(ctx->out, "%s\n", l->line); return 0; } /* NOTREACHED */ return -1; } static int known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) { struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; enum sshkey_fp_rep rep; int fptype; char *fp; fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; if (l->status == HKF_STATUS_MATCHED) { if (delete_host) { if (l->marker != MRK_NONE) { /* Don't remove CA and revocation lines */ fprintf(ctx->out, "%s\n", l->line); } else { /* * Hostname matches and has no CA/revoke * marker, delete it by *not* writing the * line to ctx->out. */ ctx->found_key = 1; if (!quiet) printf("# Host %s found: line %ld\n", ctx->host, l->linenum); } return 0; } else if (find_host) { ctx->found_key = 1; if (!quiet) { printf("# Host %s found: line %ld %s\n", ctx->host, l->linenum, l->marker == MRK_CA ? "CA" : (l->marker == MRK_REVOKE ? "REVOKED" : "")); } if (hash_hosts) known_hosts_hash(l, ctx); else if (print_fingerprint) { fp = sshkey_fingerprint(l->key, fptype, rep); printf("%s %s %s %s\n", ctx->host, sshkey_type(l->key), fp, l->comment); free(fp); } else fprintf(ctx->out, "%s\n", l->line); return 0; } } else if (delete_host) { /* Retain non-matching hosts when deleting */ if (l->status == HKF_STATUS_INVALID) { ctx->invalid = 1; logit("%s:%ld: invalid line", l->path, l->linenum); } fprintf(ctx->out, "%s\n", l->line); } return 0; } static void do_known_hosts(struct passwd *pw, const char *name) { char *cp, tmp[PATH_MAX], old[PATH_MAX]; int r, fd, oerrno, inplace = 0; struct known_hosts_ctx ctx; u_int foreach_options; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); if (strlcpy(identity_file, cp, sizeof(identity_file)) >= sizeof(identity_file)) fatal("Specified known hosts path too long"); free(cp); have_identity = 1; } memset(&ctx, 0, sizeof(ctx)); ctx.out = stdout; ctx.host = name; /* * Find hosts goes to stdout, hash and deletions happen in-place * A corner case is ssh-keygen -HF foo, which should go to stdout */ if (!find_host && (hash_hosts || delete_host)) { if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || strlcat(old, ".old", sizeof(old)) >= sizeof(old)) fatal("known_hosts path too long"); umask(077); if ((fd = mkstemp(tmp)) == -1) fatal("mkstemp: %s", strerror(errno)); if ((ctx.out = fdopen(fd, "w")) == NULL) { oerrno = errno; unlink(tmp); fatal("fdopen: %s", strerror(oerrno)); } inplace = 1; } /* XXX support identity_file == "-" for stdin */ foreach_options = find_host ? HKF_WANT_MATCH : 0; foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0; if ((r = hostkeys_foreach(identity_file, hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, name, NULL, foreach_options)) != 0) { if (inplace) unlink(tmp); fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); } if (inplace) fclose(ctx.out); if (ctx.invalid) { error("%s is not a valid known_hosts file.", identity_file); if (inplace) { error("Not replacing existing known_hosts " "file because of errors"); unlink(tmp); } exit(1); } else if (delete_host && !ctx.found_key) { logit("Host %s not found in %s", name, identity_file); if (inplace) unlink(tmp); } else if (inplace) { /* Backup existing file */ if (unlink(old) == -1 && errno != ENOENT) fatal("unlink %.100s: %s", old, strerror(errno)); if (link(identity_file, old) == -1) fatal("link %.100s to %.100s: %s", identity_file, old, strerror(errno)); /* Move new one into place */ if (rename(tmp, identity_file) == -1) { error("rename\"%s\" to \"%s\": %s", tmp, identity_file, strerror(errno)); unlink(tmp); unlink(old); exit(1); } printf("%s updated.\n", identity_file); printf("Original contents retained as %s\n", old); if (ctx.has_unhashed) { logit("WARNING: %s contains unhashed entries", old); logit("Delete this file to ensure privacy " "of hostnames"); } } exit (find_host && !ctx.found_key); } /* * Perform changing a passphrase. The argument is the passwd structure * for the current user. */ static void do_change_passphrase(struct passwd *pw) { char *comment; char *old_passphrase, *passphrase1, *passphrase2; struct stat st; struct sshkey *private; int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s", identity_file, strerror(errno)); /* Try to load the file with empty passphrase. */ r = sshkey_load_private(identity_file, "", &private, &comment); if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { if (identity_passphrase) old_passphrase = xstrdup(identity_passphrase); else old_passphrase = read_passphrase("Enter old passphrase: ", RP_ALLOW_STDIN); r = sshkey_load_private(identity_file, old_passphrase, &private, &comment); explicit_bzero(old_passphrase, strlen(old_passphrase)); free(old_passphrase); if (r != 0) goto badkey; } else if (r != 0) { badkey: fatal("Failed to load key %s: %s", identity_file, ssh_err(r)); } if (comment) printf("Key has comment '%s'\n", comment); /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { passphrase1 = xstrdup(identity_new_passphrase); passphrase2 = NULL; } else { passphrase1 = read_passphrase("Enter new passphrase (empty for no " "passphrase): ", RP_ALLOW_STDIN); passphrase2 = read_passphrase("Enter same passphrase again: ", RP_ALLOW_STDIN); /* Verify that they are the same. */ if (strcmp(passphrase1, passphrase2) != 0) { explicit_bzero(passphrase1, strlen(passphrase1)); explicit_bzero(passphrase2, strlen(passphrase2)); free(passphrase1); free(passphrase2); printf("Pass phrases do not match. Try again.\n"); exit(1); } /* Destroy the other copy. */ explicit_bzero(passphrase2, strlen(passphrase2)); free(passphrase2); } /* Save the file using the new passphrase. */ if ((r = sshkey_save_private(private, identity_file, passphrase1, comment, use_new_format, new_format_cipher, rounds)) != 0) { error("Saving key \"%s\" failed: %s.", identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); sshkey_free(private); free(comment); exit(1); } /* Destroy the passphrase and the copy of the key in memory. */ explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); sshkey_free(private); /* Destroys contents */ free(comment); printf("Your identification has been saved with the new passphrase.\n"); exit(0); } /* * Print the SSHFP RR. */ static int do_print_resource_record(struct passwd *pw, char *fname, char *hname) { struct sshkey *public; char *comment = NULL; struct stat st; int r; if (fname == NULL) fatal("%s: no filename", __func__); if (stat(fname, &st) < 0) { if (errno == ENOENT) return 0; fatal("%s: %s", fname, strerror(errno)); } if ((r = sshkey_load_public(fname, &public, &comment)) != 0) fatal("Failed to read v2 public key from \"%s\": %s.", fname, ssh_err(r)); export_dns_rr(hname, public, stdout, print_generic); sshkey_free(public); free(comment); return 1; } /* * Change the comment of a private key file. */ static void do_change_comment(struct passwd *pw) { char new_comment[1024], *comment, *passphrase; struct sshkey *private; struct sshkey *public; struct stat st; FILE *f; int r, fd; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s", identity_file, strerror(errno)); if ((r = sshkey_load_private(identity_file, "", &private, &comment)) == 0) passphrase = xstrdup(""); else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) fatal("Cannot load private key \"%s\": %s.", identity_file, ssh_err(r)); else { if (identity_passphrase) passphrase = xstrdup(identity_passphrase); else if (identity_new_passphrase) passphrase = xstrdup(identity_new_passphrase); else passphrase = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); /* Try to load using the passphrase. */ if ((r = sshkey_load_private(identity_file, passphrase, &private, &comment)) != 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); fatal("Cannot load private key \"%s\": %s.", identity_file, ssh_err(r)); } } if (private->type != KEY_RSA1 && private->type != KEY_ED25519 && !use_new_format) { error("Comments are only supported for RSA1 or keys stored in " "the new format (-o)."); explicit_bzero(passphrase, strlen(passphrase)); sshkey_free(private); exit(1); } printf("Key now has comment '%s'\n", comment); if (identity_comment) { strlcpy(new_comment, identity_comment, sizeof(new_comment)); } else { printf("Enter new comment: "); fflush(stdout); if (!fgets(new_comment, sizeof(new_comment), stdin)) { explicit_bzero(passphrase, strlen(passphrase)); sshkey_free(private); exit(1); } new_comment[strcspn(new_comment, "\n")] = '\0'; } /* Save the file using the new passphrase. */ if ((r = sshkey_save_private(private, identity_file, passphrase, new_comment, use_new_format, new_format_cipher, rounds)) != 0) { error("Saving key \"%s\" failed: %s", identity_file, ssh_err(r)); explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); sshkey_free(private); free(comment); exit(1); } explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); if ((r = sshkey_from_private(private, &public)) != 0) fatal("key_from_private failed: %s", ssh_err(r)); sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) fatal("Could not save your public key in %s", identity_file); f = fdopen(fd, "w"); if (f == NULL) fatal("fdopen %s failed: %s", identity_file, strerror(errno)); if ((r = sshkey_write(public, f)) != 0) fatal("write key failed: %s", ssh_err(r)); sshkey_free(public); fprintf(f, " %s\n", new_comment); fclose(f); free(comment); printf("The comment in your key file has been changed.\n"); exit(0); } static void add_flag_option(struct sshbuf *c, const char *name) { int r; debug3("%s: %s", __func__, name); if ((r = sshbuf_put_cstring(c, name)) != 0 || (r = sshbuf_put_string(c, NULL, 0)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } static void add_string_option(struct sshbuf *c, const char *name, const char *value) { struct sshbuf *b; int r; debug3("%s: %s=%s", __func__, name, value); if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_cstring(b, value)) != 0 || (r = sshbuf_put_cstring(c, name)) != 0 || (r = sshbuf_put_stringb(c, b)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(b); } #define OPTIONS_CRITICAL 1 #define OPTIONS_EXTENSIONS 2 static void prepare_options_buf(struct sshbuf *c, int which) { sshbuf_reset(c); if ((which & OPTIONS_CRITICAL) != 0 && certflags_command != NULL) add_string_option(c, "force-command", certflags_command); if ((which & OPTIONS_EXTENSIONS) != 0 && (certflags_flags & CERTOPT_X_FWD) != 0) add_flag_option(c, "permit-X11-forwarding"); if ((which & OPTIONS_EXTENSIONS) != 0 && (certflags_flags & CERTOPT_AGENT_FWD) != 0) add_flag_option(c, "permit-agent-forwarding"); if ((which & OPTIONS_EXTENSIONS) != 0 && (certflags_flags & CERTOPT_PORT_FWD) != 0) add_flag_option(c, "permit-port-forwarding"); if ((which & OPTIONS_EXTENSIONS) != 0 && (certflags_flags & CERTOPT_PTY) != 0) add_flag_option(c, "permit-pty"); if ((which & OPTIONS_EXTENSIONS) != 0 && (certflags_flags & CERTOPT_USER_RC) != 0) add_flag_option(c, "permit-user-rc"); if ((which & OPTIONS_CRITICAL) != 0 && certflags_src_addr != NULL) add_string_option(c, "source-address", certflags_src_addr); } static struct sshkey * load_pkcs11_key(char *path) { #ifdef ENABLE_PKCS11 struct sshkey **keys = NULL, *public, *private = NULL; int r, i, nkeys; if ((r = sshkey_load_public(path, &public, NULL)) != 0) fatal("Couldn't load CA public key \"%s\": %s", path, ssh_err(r)); nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); debug3("%s: %d keys", __func__, nkeys); if (nkeys <= 0) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { if (sshkey_equal_public(public, keys[i])) { private = keys[i]; continue; } sshkey_free(keys[i]); } free(keys); sshkey_free(public); return private; #else fatal("no pkcs11 support"); #endif /* ENABLE_PKCS11 */ } static void do_ca_sign(struct passwd *pw, int argc, char **argv) { int r, i, fd; u_int n; struct sshkey *ca, *public; char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; FILE *f; #ifdef ENABLE_PKCS11 pkcs11_init(1); #endif tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); if (pkcs11provider != NULL) { if ((ca = load_pkcs11_key(tmp)) == NULL) fatal("No PKCS#11 key matching %s found", ca_key_path); } else ca = load_identity(tmp); free(tmp); for (i = 0; i < argc; i++) { /* Split list of principals */ n = 0; if (cert_principals != NULL) { otmp = tmp = xstrdup(cert_principals); plist = NULL; for (; (cp = strsep(&tmp, ",")) != NULL; n++) { plist = xreallocarray(plist, n + 1, sizeof(*plist)); if (*(plist[n] = xstrdup(cp)) == '\0') fatal("Empty principal name"); } free(otmp); } tmp = tilde_expand_filename(argv[i], pw->pw_uid); if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) fatal("%s: unable to open \"%s\": %s", __func__, tmp, ssh_err(r)); if (public->type != KEY_RSA && public->type != KEY_DSA && public->type != KEY_ECDSA && public->type != KEY_ED25519) fatal("%s: key \"%s\" type %s cannot be certified", __func__, tmp, sshkey_type(public)); /* Prepare certificate to sign */ if ((r = sshkey_to_certified(public)) != 0) fatal("Could not upgrade key %s to certificate: %s", tmp, ssh_err(r)); public->cert->type = cert_key_type; public->cert->serial = (u_int64_t)cert_serial; public->cert->key_id = xstrdup(cert_key_id); public->cert->nprincipals = n; public->cert->principals = plist; public->cert->valid_after = cert_valid_from; public->cert->valid_before = cert_valid_to; prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL); prepare_options_buf(public->cert->extensions, OPTIONS_EXTENSIONS); if ((r = sshkey_from_private(ca, &public->cert->signature_key)) != 0) fatal("key_from_private (ca key): %s", ssh_err(r)); if (sshkey_certify(public, ca) != 0) fatal("Couldn't not certify key %s", tmp); if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) *cp = '\0'; xasprintf(&out, "%s-cert.pub", tmp); free(tmp); if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) fatal("Could not open \"%s\" for writing: %s", out, strerror(errno)); if ((f = fdopen(fd, "w")) == NULL) fatal("%s: fdopen: %s", __func__, strerror(errno)); if ((r = sshkey_write(public, f)) != 0) fatal("Could not write certified key to %s: %s", out, ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { sshkey_format_cert_validity(public->cert, valid, sizeof(valid)); logit("Signed %s key %s: id \"%s\" serial %llu%s%s " "valid %s", sshkey_cert_type(public), out, public->cert->key_id, (unsigned long long)public->cert->serial, cert_principals != NULL ? " for " : "", cert_principals != NULL ? cert_principals : "", valid); } sshkey_free(public); free(out); } #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif exit(0); } static u_int64_t parse_relative_time(const char *s, time_t now) { int64_t mul, secs; mul = *s == '-' ? -1 : 1; if ((secs = convtime(s + 1)) == -1) fatal("Invalid relative certificate time %s", s); if (mul == -1 && secs > now) fatal("Certificate time %s cannot be represented", s); return now + (u_int64_t)(secs * mul); } static u_int64_t parse_absolute_time(const char *s) { struct tm tm; time_t tt; char buf[32], *fmt; /* * POSIX strptime says "The application shall ensure that there * is white-space or other non-alphanumeric characters between * any two conversion specifications" so arrange things this way. */ switch (strlen(s)) { case 8: fmt = "%Y-%m-%d"; snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); break; case 14: fmt = "%Y-%m-%dT%H:%M:%S"; snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", s, s + 4, s + 6, s + 8, s + 10, s + 12); break; default: fatal("Invalid certificate time format %s", s); } memset(&tm, 0, sizeof(tm)); if (strptime(buf, fmt, &tm) == NULL) fatal("Invalid certificate time %s", s); if ((tt = mktime(&tm)) < 0) fatal("Certificate time %s cannot be represented", s); return (u_int64_t)tt; } static void parse_cert_times(char *timespec) { char *from, *to; time_t now = time(NULL); int64_t secs; /* +timespec relative to now */ if (*timespec == '+' && strchr(timespec, ':') == NULL) { if ((secs = convtime(timespec + 1)) == -1) fatal("Invalid relative certificate life %s", timespec); cert_valid_to = now + secs; /* * Backdate certificate one minute to avoid problems on hosts * with poorly-synchronised clocks. */ cert_valid_from = ((now - 59)/ 60) * 60; return; } /* * from:to, where * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS */ from = xstrdup(timespec); to = strchr(from, ':'); if (to == NULL || from == to || *(to + 1) == '\0') fatal("Invalid certificate life specification %s", timespec); *to++ = '\0'; if (*from == '-' || *from == '+') cert_valid_from = parse_relative_time(from, now); else cert_valid_from = parse_absolute_time(from); if (*to == '-' || *to == '+') cert_valid_to = parse_relative_time(to, now); else cert_valid_to = parse_absolute_time(to); if (cert_valid_to <= cert_valid_from) fatal("Empty certificate validity interval"); free(from); } static void add_cert_option(char *opt) { char *val; if (strcasecmp(opt, "clear") == 0) certflags_flags = 0; else if (strcasecmp(opt, "no-x11-forwarding") == 0) certflags_flags &= ~CERTOPT_X_FWD; else if (strcasecmp(opt, "permit-x11-forwarding") == 0) certflags_flags |= CERTOPT_X_FWD; else if (strcasecmp(opt, "no-agent-forwarding") == 0) certflags_flags &= ~CERTOPT_AGENT_FWD; else if (strcasecmp(opt, "permit-agent-forwarding") == 0) certflags_flags |= CERTOPT_AGENT_FWD; else if (strcasecmp(opt, "no-port-forwarding") == 0) certflags_flags &= ~CERTOPT_PORT_FWD; else if (strcasecmp(opt, "permit-port-forwarding") == 0) certflags_flags |= CERTOPT_PORT_FWD; else if (strcasecmp(opt, "no-pty") == 0) certflags_flags &= ~CERTOPT_PTY; else if (strcasecmp(opt, "permit-pty") == 0) certflags_flags |= CERTOPT_PTY; else if (strcasecmp(opt, "no-user-rc") == 0) certflags_flags &= ~CERTOPT_USER_RC; else if (strcasecmp(opt, "permit-user-rc") == 0) certflags_flags |= CERTOPT_USER_RC; else if (strncasecmp(opt, "force-command=", 14) == 0) { val = opt + 14; if (*val == '\0') fatal("Empty force-command option"); if (certflags_command != NULL) fatal("force-command already specified"); certflags_command = xstrdup(val); } else if (strncasecmp(opt, "source-address=", 15) == 0) { val = opt + 15; if (*val == '\0') fatal("Empty source-address option"); if (certflags_src_addr != NULL) fatal("source-address already specified"); if (addr_match_cidr_list(NULL, val) != 0) fatal("Invalid source-address list"); certflags_src_addr = xstrdup(val); } else fatal("Unsupported certificate option \"%s\"", opt); } static void show_options(struct sshbuf *optbuf, int in_critical) { char *name, *arg; struct sshbuf *options, *option = NULL; int r; if ((options = sshbuf_fromb(optbuf)) == NULL) fatal("%s: sshbuf_fromb failed", __func__); while (sshbuf_len(options) != 0) { sshbuf_free(option); option = NULL; if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 || (r = sshbuf_froms(options, &option)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); printf(" %s", name); if (!in_critical && (strcmp(name, "permit-X11-forwarding") == 0 || strcmp(name, "permit-agent-forwarding") == 0 || strcmp(name, "permit-port-forwarding") == 0 || strcmp(name, "permit-pty") == 0 || strcmp(name, "permit-user-rc") == 0)) printf("\n"); else if (in_critical && (strcmp(name, "force-command") == 0 || strcmp(name, "source-address") == 0)) { if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); printf(" %s\n", arg); free(arg); } else { printf(" UNKNOWN OPTION (len %zu)\n", sshbuf_len(option)); sshbuf_reset(option); } free(name); if (sshbuf_len(option) != 0) fatal("Option corrupt: extra data at end"); } sshbuf_free(option); sshbuf_free(options); } static void print_cert(struct sshkey *key) { char valid[64], *key_fp, *ca_fp; u_int i; key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); ca_fp = sshkey_fingerprint(key->cert->signature_key, fingerprint_hash, SSH_FP_DEFAULT); if (key_fp == NULL || ca_fp == NULL) fatal("%s: sshkey_fingerprint fail", __func__); sshkey_format_cert_validity(key->cert, valid, sizeof(valid)); printf(" Type: %s %s certificate\n", sshkey_ssh_name(key), sshkey_cert_type(key)); printf(" Public key: %s %s\n", sshkey_type(key), key_fp); printf(" Signing CA: %s %s\n", sshkey_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); printf(" Serial: %llu\n", (unsigned long long)key->cert->serial); printf(" Valid: %s\n", valid); printf(" Principals: "); if (key->cert->nprincipals == 0) printf("(none)\n"); else { for (i = 0; i < key->cert->nprincipals; i++) printf("\n %s", key->cert->principals[i]); printf("\n"); } printf(" Critical Options: "); if (sshbuf_len(key->cert->critical) == 0) printf("(none)\n"); else { printf("\n"); show_options(key->cert->critical, 1); } printf(" Extensions: "); if (sshbuf_len(key->cert->extensions) == 0) printf("(none)\n"); else { printf("\n"); show_options(key->cert->extensions, 0); } } static void do_show_cert(struct passwd *pw) { struct sshkey *key = NULL; struct stat st; int r, is_stdin = 0, ok = 0; FILE *f; char *cp, line[SSH_MAX_PUBKEY_BYTES]; const char *path; long int lnum = 0; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); path = identity_file; if (strcmp(path, "-") == 0) { f = stdin; path = "(stdin)"; is_stdin = 1; } else if ((f = fopen(identity_file, "r")) == NULL) fatal("fopen %s: %s", identity_file, strerror(errno)); while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) { sshkey_free(key); key = NULL; /* Trim leading space and comments */ cp = line + strspn(line, " \t"); if (*cp == '#' || *cp == '\0') continue; if ((key = sshkey_new(KEY_UNSPEC)) == NULL) fatal("key_new"); if ((r = sshkey_read(key, &cp)) != 0) { error("%s:%lu: invalid key: %s", path, lnum, ssh_err(r)); continue; } if (!sshkey_is_cert(key)) { error("%s:%lu is not a certificate", path, lnum); continue; } ok = 1; if (!is_stdin && lnum == 1) printf("%s:\n", path); else printf("%s:%lu:\n", path, lnum); print_cert(key); } sshkey_free(key); fclose(f); exit(ok ? 0 : 1); } static void load_krl(const char *path, struct ssh_krl **krlp) { struct sshbuf *krlbuf; int r, fd; if ((krlbuf = sshbuf_new()) == NULL) fatal("sshbuf_new failed"); if ((fd = open(path, O_RDONLY)) == -1) fatal("open %s: %s", path, strerror(errno)); if ((r = sshkey_load_file(fd, krlbuf)) != 0) fatal("Unable to load KRL: %s", ssh_err(r)); close(fd); /* XXX check sigs */ if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 || *krlp == NULL) fatal("Invalid KRL file: %s", ssh_err(r)); sshbuf_free(krlbuf); } static void update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, const struct sshkey *ca, struct ssh_krl *krl) { struct sshkey *key = NULL; u_long lnum = 0; char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; unsigned long long serial, serial2; int i, was_explicit_key, was_sha1, r; FILE *krl_spec; path = tilde_expand_filename(file, pw->pw_uid); if (strcmp(path, "-") == 0) { krl_spec = stdin; free(path); path = xstrdup("(standard input)"); } else if ((krl_spec = fopen(path, "r")) == NULL) fatal("fopen %s: %s", path, strerror(errno)); if (!quiet) printf("Revoking from %s\n", path); while (read_keyfile_line(krl_spec, path, line, sizeof(line), &lnum) == 0) { was_explicit_key = was_sha1 = 0; cp = line + strspn(line, " \t"); /* Trim trailing space, comments and strip \n */ for (i = 0, r = -1; cp[i] != '\0'; i++) { if (cp[i] == '#' || cp[i] == '\n') { cp[i] = '\0'; break; } if (cp[i] == ' ' || cp[i] == '\t') { /* Remember the start of a span of whitespace */ if (r == -1) r = i; } else r = -1; } if (r != -1) cp[r] = '\0'; if (*cp == '\0') continue; if (strncasecmp(cp, "serial:", 7) == 0) { if (ca == NULL && !wild_ca) { fatal("revoking certificates by serial number " "requires specification of a CA key"); } cp += 7; cp = cp + strspn(cp, " \t"); errno = 0; serial = strtoull(cp, &ep, 0); if (*cp == '\0' || (*ep != '\0' && *ep != '-')) fatal("%s:%lu: invalid serial \"%s\"", path, lnum, cp); if (errno == ERANGE && serial == ULLONG_MAX) fatal("%s:%lu: serial out of range", path, lnum); serial2 = serial; if (*ep == '-') { cp = ep + 1; errno = 0; serial2 = strtoull(cp, &ep, 0); if (*cp == '\0' || *ep != '\0') fatal("%s:%lu: invalid serial \"%s\"", path, lnum, cp); if (errno == ERANGE && serial2 == ULLONG_MAX) fatal("%s:%lu: serial out of range", path, lnum); if (serial2 <= serial) fatal("%s:%lu: invalid serial range " "%llu:%llu", path, lnum, (unsigned long long)serial, (unsigned long long)serial2); } if (ssh_krl_revoke_cert_by_serial_range(krl, ca, serial, serial2) != 0) { fatal("%s: revoke serial failed", __func__); } } else if (strncasecmp(cp, "id:", 3) == 0) { if (ca == NULL && !wild_ca) { fatal("revoking certificates by key ID " "requires specification of a CA key"); } cp += 3; cp = cp + strspn(cp, " \t"); if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) fatal("%s: revoke key ID failed", __func__); } else { if (strncasecmp(cp, "key:", 4) == 0) { cp += 4; cp = cp + strspn(cp, " \t"); was_explicit_key = 1; } else if (strncasecmp(cp, "sha1:", 5) == 0) { cp += 5; cp = cp + strspn(cp, " \t"); was_sha1 = 1; } else { /* * Just try to process the line as a key. * Parsing will fail if it isn't. */ } if ((key = sshkey_new(KEY_UNSPEC)) == NULL) fatal("key_new"); if ((r = sshkey_read(key, &cp)) != 0) fatal("%s:%lu: invalid key: %s", path, lnum, ssh_err(r)); if (was_explicit_key) r = ssh_krl_revoke_key_explicit(krl, key); else if (was_sha1) r = ssh_krl_revoke_key_sha1(krl, key); else r = ssh_krl_revoke_key(krl, key); if (r != 0) fatal("%s: revoke key failed: %s", __func__, ssh_err(r)); sshkey_free(key); } } if (strcmp(path, "-") != 0) fclose(krl_spec); free(path); } static void do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) { struct ssh_krl *krl; struct stat sb; struct sshkey *ca = NULL; int fd, i, r, wild_ca = 0; char *tmp; struct sshbuf *kbuf; if (*identity_file == '\0') fatal("KRL generation requires an output file"); if (stat(identity_file, &sb) == -1) { if (errno != ENOENT) fatal("Cannot access KRL \"%s\": %s", identity_file, strerror(errno)); if (updating) fatal("KRL \"%s\" does not exist", identity_file); } if (ca_key_path != NULL) { if (strcasecmp(ca_key_path, "none") == 0) wild_ca = 1; else { tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) fatal("Cannot load CA public key %s: %s", tmp, ssh_err(r)); free(tmp); } } if (updating) load_krl(identity_file, &krl); else if ((krl = ssh_krl_init()) == NULL) fatal("couldn't create KRL"); if (cert_serial != 0) ssh_krl_set_version(krl, cert_serial); if (identity_comment != NULL) ssh_krl_set_comment(krl, identity_comment); for (i = 0; i < argc; i++) update_krl_from_file(pw, argv[i], wild_ca, ca, krl); if ((kbuf = sshbuf_new()) == NULL) fatal("sshbuf_new failed"); if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0) fatal("Couldn't generate KRL"); if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) fatal("open %s: %s", identity_file, strerror(errno)); if (atomicio(vwrite, fd, (void *)sshbuf_ptr(kbuf), sshbuf_len(kbuf)) != sshbuf_len(kbuf)) fatal("write %s: %s", identity_file, strerror(errno)); close(fd); sshbuf_free(kbuf); ssh_krl_free(krl); sshkey_free(ca); } static void do_check_krl(struct passwd *pw, int argc, char **argv) { int i, r, ret = 0; char *comment; struct ssh_krl *krl; struct sshkey *k; if (*identity_file == '\0') fatal("KRL checking requires an input file"); load_krl(identity_file, &krl); for (i = 0; i < argc; i++) { if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0) fatal("Cannot load public key %s: %s", argv[i], ssh_err(r)); r = ssh_krl_check_key(krl, k); printf("%s%s%s%s: %s\n", argv[i], *comment ? " (" : "", comment, *comment ? ")" : "", r == 0 ? "ok" : "REVOKED"); if (r != 0) ret = 1; sshkey_free(k); free(comment); } ssh_krl_free(krl); exit(ret); } static void usage(void) { fprintf(stderr, "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]\n" " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" " ssh-keygen -y [-f input_keyfile]\n" " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" " ssh-keygen -B [-f input_keyfile]\n"); #ifdef ENABLE_PKCS11 fprintf(stderr, " ssh-keygen -D pkcs11\n"); #endif fprintf(stderr, " ssh-keygen -F hostname [-f known_hosts_file] [-l]\n" " ssh-keygen -H [-f known_hosts_file]\n" " ssh-keygen -R hostname [-f known_hosts_file]\n" " ssh-keygen -r hostname [-f input_keyfile] [-g]\n" #ifdef WITH_OPENSSL " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" " [-j start_line] [-K checkpt] [-W generator]\n" #endif " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" " [-O option] [-V validity_interval] [-z serial_number] file ...\n" " ssh-keygen -L [-f input_keyfile]\n" " ssh-keygen -A\n" " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" " file ...\n" " ssh-keygen -Q -f krl_file file ...\n"); exit(1); } /* * Main program for key management. */ int main(int argc, char **argv) { char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; char *rr_hostname = NULL, *ep, *fp, *ra; struct sshkey *private, *public; struct passwd *pw; struct stat st; int r, opt, type, fd; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; FILE *f; const char *errstr; #ifdef WITH_OPENSSL /* Moduli generation/screening */ char out_file[PATH_MAX], *checkpoint = NULL; u_int32_t memory = 0, generator_wanted = 0; int do_gen_candidates = 0, do_screen_candidates = 0; unsigned long start_lineno = 0, lines_to_process = 0; BIGNUM *start = NULL; #endif extern int optind; extern char *optarg; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); __progname = ssh_get_progname(argv[0]); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); seed_rng(); /* we need this for the home * directory. */ pw = getpwuid(getuid()); if (!pw) fatal("No user exists for uid %lu", (u_long)getuid()); if (gethostname(hostname, sizeof(hostname)) < 0) fatal("gethostname: %s", strerror(errno)); /* Remaining characters: UYdw */ while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; break; case 'b': bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr); if (errstr) fatal("Bits has bad value %s (%s)", optarg, errstr); break; case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) fatal("Invalid hash algorithm \"%s\"", optarg); break; case 'F': find_host = 1; rr_hostname = optarg; break; case 'H': hash_hosts = 1; break; case 'I': cert_key_id = optarg; break; case 'R': delete_host = 1; rr_hostname = optarg; break; case 'L': show_cert = 1; break; case 'l': print_fingerprint = 1; break; case 'B': print_bubblebabble = 1; break; case 'm': if (strcasecmp(optarg, "RFC4716") == 0 || strcasecmp(optarg, "ssh2") == 0) { convert_format = FMT_RFC4716; break; } if (strcasecmp(optarg, "PKCS8") == 0) { convert_format = FMT_PKCS8; break; } if (strcasecmp(optarg, "PEM") == 0) { convert_format = FMT_PEM; break; } fatal("Unsupported conversion format \"%s\"", optarg); case 'n': cert_principals = optarg; break; case 'o': use_new_format = 1; break; case 'p': change_passphrase = 1; break; case 'c': change_comment = 1; break; case 'f': if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= sizeof(identity_file)) fatal("Identity filename too long"); have_identity = 1; break; case 'g': print_generic = 1; break; case 'P': identity_passphrase = optarg; break; case 'N': identity_new_passphrase = optarg; break; case 'Q': check_krl = 1; break; case 'O': add_cert_option(optarg); break; case 'Z': new_format_cipher = optarg; break; case 'C': identity_comment = optarg; break; case 'q': quiet = 1; break; case 'e': case 'x': /* export key */ convert_to = 1; break; case 'h': cert_key_type = SSH2_CERT_TYPE_HOST; certflags_flags = 0; break; case 'k': gen_krl = 1; break; case 'i': case 'X': /* import key */ convert_from = 1; break; case 'y': print_public = 1; break; case 's': ca_key_path = optarg; break; case 't': key_type_name = optarg; break; case 'D': pkcs11provider = optarg; break; case 'u': update_krl = 1; break; case 'v': if (log_level == SYSLOG_LEVEL_INFO) log_level = SYSLOG_LEVEL_DEBUG1; else { if (log_level >= SYSLOG_LEVEL_DEBUG1 && log_level < SYSLOG_LEVEL_DEBUG3) log_level++; } break; case 'r': rr_hostname = optarg; break; case 'a': rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); if (errstr) fatal("Invalid number: %s (%s)", optarg, errstr); break; case 'V': parse_cert_times(optarg); break; case 'z': errno = 0; cert_serial = strtoull(optarg, &ep, 10); if (*optarg < '0' || *optarg > '9' || *ep != '\0' || (errno == ERANGE && cert_serial == ULLONG_MAX)) fatal("Invalid serial number \"%s\"", optarg); break; #ifdef WITH_OPENSSL /* Moduli generation/screening */ case 'W': generator_wanted = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); if (errstr) fatal("Desired generator has bad value: %s (%s)", optarg, errstr); break; case 'M': memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); if (errstr) fatal("Memory limit is %s: %s", errstr, optarg); break; case 'G': do_gen_candidates = 1; if (strlcpy(out_file, optarg, sizeof(out_file)) >= sizeof(out_file)) fatal("Output filename too long"); break; case 'T': do_screen_candidates = 1; if (strlcpy(out_file, optarg, sizeof(out_file)) >= sizeof(out_file)) fatal("Output filename too long"); break; case 'K': if (strlen(optarg) >= PATH_MAX) fatal("Checkpoint filename too long"); checkpoint = xstrdup(optarg); break; case 'S': /* XXX - also compare length against bits */ if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); break; #endif /* WITH_OPENSSL */ case '?': default: usage(); } } /* reinit */ log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); argv += optind; argc -= optind; if (ca_key_path != NULL) { if (argc < 1 && !gen_krl) { error("Too few arguments."); usage(); } } else if (argc > 0 && !gen_krl && !check_krl) { error("Too many arguments."); usage(); } if (change_passphrase && change_comment) { error("Can only have one of -p and -c."); usage(); } if (print_fingerprint && (delete_host || hash_hosts)) { error("Cannot use -l with -H or -R."); usage(); } if (gen_krl) { do_gen_krl(pw, update_krl, argc, argv); return (0); } if (check_krl) { do_check_krl(pw, argc, argv); return (0); } if (ca_key_path != NULL) { if (cert_key_id == NULL) fatal("Must specify key id (-I) when certifying"); do_ca_sign(pw, argc, argv); } if (show_cert) do_show_cert(pw); if (delete_host || hash_hosts || find_host) do_known_hosts(pw, rr_hostname); if (pkcs11provider != NULL) do_download(pw); if (print_fingerprint || print_bubblebabble) do_fingerprint(pw); if (change_passphrase) do_change_passphrase(pw); if (change_comment) do_change_comment(pw); #ifdef WITH_OPENSSL if (convert_to) do_convert_to(pw); if (convert_from) do_convert_from(pw); #endif if (print_public) do_print_public(pw); if (rr_hostname != NULL) { unsigned int n = 0; if (have_identity) { n = do_print_resource_record(pw, identity_file, rr_hostname); if (n == 0) fatal("%s: %s", identity_file, strerror(errno)); exit(0); } else { n += do_print_resource_record(pw, _PATH_HOST_RSA_KEY_FILE, rr_hostname); n += do_print_resource_record(pw, _PATH_HOST_DSA_KEY_FILE, rr_hostname); n += do_print_resource_record(pw, _PATH_HOST_ECDSA_KEY_FILE, rr_hostname); n += do_print_resource_record(pw, _PATH_HOST_ED25519_KEY_FILE, rr_hostname); if (n == 0) fatal("no keys found."); exit(0); } } #ifdef WITH_OPENSSL if (do_gen_candidates) { FILE *out = fopen(out_file, "w"); if (out == NULL) { error("Couldn't open modulus candidate file \"%s\": %s", out_file, strerror(errno)); return (1); } if (bits == 0) bits = DEFAULT_BITS; if (gen_candidates(out, memory, bits, start) != 0) fatal("modulus candidate generation failed"); return (0); } if (do_screen_candidates) { FILE *in; FILE *out = fopen(out_file, "a"); if (have_identity && strcmp(identity_file, "-") != 0) { if ((in = fopen(identity_file, "r")) == NULL) { fatal("Couldn't open modulus candidate " "file \"%s\": %s", identity_file, strerror(errno)); } } else in = stdin; if (out == NULL) { fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } if (prime_test(in, out, rounds == 0 ? 100 : rounds, generator_wanted, checkpoint, start_lineno, lines_to_process) != 0) fatal("modulus screening failed"); return (0); } #endif if (gen_all_hostkeys) { do_gen_all_hostkeys(pw); return (0); } if (key_type_name == NULL) key_type_name = DEFAULT_KEY_TYPE_NAME; type = sshkey_type_from_name(key_type_name); type_bits_valid(type, key_type_name, &bits); if (!quiet) printf("Generating public/private %s key pair.\n", key_type_name); if ((r = sshkey_generate(type, bits, &private)) != 0) fatal("key_generate failed"); if ((r = sshkey_from_private(private, &public)) != 0) fatal("key_from_private failed: %s\n", ssh_err(r)); if (!have_identity) ask_filename(pw, "Enter file in which to save the key"); /* Create ~/.ssh directory if it doesn't already exist. */ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR); if (strstr(identity_file, dotsshdir) != NULL) { if (stat(dotsshdir, &st) < 0) { if (errno != ENOENT) { error("Could not stat %s: %s", dotsshdir, strerror(errno)); } else if (mkdir(dotsshdir, 0700) < 0) { error("Could not create directory '%s': %s", dotsshdir, strerror(errno)); } else if (!quiet) printf("Created directory '%s'.\n", dotsshdir); } } /* If the file already exists, ask the user to confirm. */ if (stat(identity_file, &st) >= 0) { char yesno[3]; printf("%s already exists.\n", identity_file); printf("Overwrite (y/n)? "); fflush(stdout); if (fgets(yesno, sizeof(yesno), stdin) == NULL) exit(1); if (yesno[0] != 'y' && yesno[0] != 'Y') exit(1); } /* Ask for a passphrase (twice). */ if (identity_passphrase) passphrase1 = xstrdup(identity_passphrase); else if (identity_new_passphrase) passphrase1 = xstrdup(identity_new_passphrase); else { passphrase_again: passphrase1 = read_passphrase("Enter passphrase (empty for no " "passphrase): ", RP_ALLOW_STDIN); passphrase2 = read_passphrase("Enter same passphrase again: ", RP_ALLOW_STDIN); if (strcmp(passphrase1, passphrase2) != 0) { /* * The passphrases do not match. Clear them and * retry. */ explicit_bzero(passphrase1, strlen(passphrase1)); explicit_bzero(passphrase2, strlen(passphrase2)); free(passphrase1); free(passphrase2); printf("Passphrases do not match. Try again.\n"); goto passphrase_again; } /* Clear the other copy of the passphrase. */ explicit_bzero(passphrase2, strlen(passphrase2)); free(passphrase2); } if (identity_comment) { strlcpy(comment, identity_comment, sizeof(comment)); } else { /* Create default comment field for the passphrase. */ snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); } /* Save the key with the given passphrase and comment. */ if ((r = sshkey_save_private(private, identity_file, passphrase1, comment, use_new_format, new_format_cipher, rounds)) != 0) { error("Saving key \"%s\" failed: %s", identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); exit(1); } /* Clear the passphrase. */ explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); /* Clear the private key and the random number generator. */ sshkey_free(private); if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); strlcat(identity_file, ".pub", sizeof(identity_file)); if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) fatal("Unable to save public key to %s: %s", identity_file, strerror(errno)); if ((f = fdopen(fd, "w")) == NULL) fatal("fdopen %s failed: %s", identity_file, strerror(errno)); if ((r = sshkey_write(public, f)) != 0) error("write key failed: %s", ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { fp = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_DEFAULT); ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("sshkey_fingerprint failed"); printf("Your public key has been saved in %s.\n", identity_file); printf("The key fingerprint is:\n"); printf("%s %s\n", fp, comment); printf("The key's randomart image is:\n"); printf("%s\n", ra); free(ra); free(fp); } sshkey_free(public); exit(0); } openssh-7.2p2/ssh-keyscan.1010064400017500001750000000104351267006270000137670ustar00djmdjm.\" $OpenBSD: ssh-keyscan.1,v 1.38 2015/11/08 23:24:03 jmc Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" .\" 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. .\" .Dd $Mdocdate: November 8 2015 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME .Nm ssh-keyscan .Nd gather ssh public keys .Sh SYNOPSIS .Nm ssh-keyscan .Bk -words .Op Fl 46cHv .Op Fl f Ar file .Op Fl p Ar port .Op Fl T Ar timeout .Op Fl t Ar type .Op Ar host | addrlist namelist .Ar ... .Ek .Sh DESCRIPTION .Nm is a utility for gathering the public ssh host keys of a number of hosts. It was designed to aid in building and verifying .Pa ssh_known_hosts files. .Nm provides a minimal interface suitable for use by shell and perl scripts. .Pp .Nm uses non-blocking socket I/O to contact as many hosts as possible in parallel, so it is very efficient. The keys from a domain of 1,000 hosts can be collected in tens of seconds, even when some of those hosts are down or do not run ssh. For scanning, one does not need login access to the machines that are being scanned, nor does the scanning process involve any encryption. .Pp The options are as follows: .Bl -tag -width Ds .It Fl 4 Forces .Nm to use IPv4 addresses only. .It Fl 6 Forces .Nm to use IPv6 addresses only. .It Fl c Request certificates from target hosts instead of plain keys. .It Fl f Ar file Read hosts or .Dq addrlist namelist pairs from .Ar file , one per line. If .Pa - is supplied instead of a filename, .Nm will read hosts or .Dq addrlist namelist pairs from the standard input. .It Fl H Hash all hostnames and addresses in the output. Hashed names may be used normally by .Nm ssh and .Nm sshd , but they do not reveal identifying information should the file's contents be disclosed. .It Fl p Ar port Port to connect to on the remote host. .It Fl T Ar timeout Set the timeout for connection attempts. If .Ar timeout seconds have elapsed since a connection was initiated to a host or since the last time anything was read from that host, then the connection is closed and the host in question considered unavailable. Default is 5 seconds. .It Fl t Ar type Specifies the type of the key to fetch from the scanned hosts. The possible values are .Dq rsa1 for protocol version 1 and .Dq dsa , .Dq ecdsa , .Dq ed25519 , or .Dq rsa for protocol version 2. Multiple values may be specified by separating them with commas. The default is to fetch .Dq rsa , .Dq ecdsa , and .Dq ed25519 keys. .It Fl v Verbose mode. Causes .Nm to print debugging messages about its progress. .El .Sh SECURITY If an ssh_known_hosts file is constructed using .Nm without verifying the keys, users will be vulnerable to .Em man in the middle attacks. On the other hand, if the security model allows such a risk, .Nm can help in the detection of tampered keyfiles or man in the middle attacks which have begun after the ssh_known_hosts file was created. .Sh FILES Input format: .Bd -literal 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 .Ed .Pp Output format for RSA1 keys: .Bd -literal host-or-namelist bits exponent modulus .Ed .Pp Output format for RSA, DSA, ECDSA, and Ed25519 keys: .Bd -literal host-or-namelist keytype base64-encoded-key .Ed .Pp Where .Ar keytype is either .Dq ecdsa-sha2-nistp256 , .Dq ecdsa-sha2-nistp384 , .Dq ecdsa-sha2-nistp521 , .Dq ssh-ed25519 , .Dq ssh-dss or .Dq ssh-rsa . .Pp .Pa /etc/ssh/ssh_known_hosts .Sh EXAMPLES Print the rsa host key for machine .Ar hostname : .Bd -literal $ ssh-keyscan hostname .Ed .Pp Find all hosts from the file .Pa ssh_hosts which have new or different keys from those in the sorted file .Pa ssh_known_hosts : .Bd -literal $ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \e sort -u - ssh_known_hosts | diff ssh_known_hosts - .Ed .Sh SEE ALSO .Xr ssh 1 , .Xr sshd 8 .Sh AUTHORS .An -nosplit .An David Mazieres Aq Mt dm@lcs.mit.edu wrote the initial version, and .An Wayne Davison Aq Mt wayned@users.sourceforge.net added support for protocol version 2. .Sh BUGS It generates "Connection closed by remote host" messages on the consoles of all the machines it scans if the server is older than version 2.9. This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. openssh-7.2p2/ssh-keyscan.c010064400017500001750000000455321267006270000140570ustar00djmdjm/* $OpenBSD: ssh-keyscan.c,v 1.105 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * * 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. */ #include "includes.h" #include #include "openbsd-compat/sys-queue.h" #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "sshbuf.h" #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "compat.h" #include "myproposal.h" #include "packet.h" #include "dispatch.h" #include "log.h" #include "atomicio.h" #include "misc.h" #include "hostfile.h" #include "ssherr.h" #include "ssh_api.h" /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. Default value is AF_UNSPEC means both IPv4 and IPv6. */ int IPv4or6 = AF_UNSPEC; int ssh_port = SSH_DEFAULT_PORT; #define KT_RSA1 1 #define KT_DSA 2 #define KT_RSA 4 #define KT_ECDSA 8 #define KT_ED25519 16 int get_cert = 0; int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; int hash_hosts = 0; /* Hash hostname on output */ #define MAXMAXFD 256 /* The number of seconds after which to give up on a TCP connection */ int timeout = 5; int maxfd; #define MAXCON (maxfd - 10) extern char *__progname; fd_set *read_wait; size_t read_wait_nfdset; int ncon; struct ssh *active_state = NULL; /* XXX needed for linking */ /* * Keep a connection structure for each file descriptor. The state * associated with file descriptor n is held in fdcon[n]. */ typedef struct Connection { u_char c_status; /* State of connection on this file desc. */ #define CS_UNUSED 0 /* File descriptor unused */ #define CS_CON 1 /* Waiting to connect/read greeting */ #define CS_SIZE 2 /* Waiting to read initial packet size */ #define CS_KEYS 3 /* Waiting to read public key packet */ int c_fd; /* Quick lookup: c->c_fd == c - fdcon */ int c_plen; /* Packet length field for ssh packet */ int c_len; /* Total bytes which must be read. */ int c_off; /* Length of data read so far. */ int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ sig_atomic_t c_done; /* SSH2 done */ char *c_namebase; /* Address to free for c_name and c_namelist */ char *c_name; /* Hostname of connection for errors */ char *c_namelist; /* Pointer to other possible addresses */ char *c_output_name; /* Hostname of connection for output */ char *c_data; /* Data read from this fd */ struct ssh *c_ssh; /* SSH-connection */ struct timeval c_tv; /* Time at which connection gets aborted */ TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */ } con; TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */ con *fdcon; static void keyprint(con *c, struct sshkey *key); static int fdlim_get(int hard) { #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlfd; if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY) return SSH_SYSFDMAX; else return hard ? rlfd.rlim_max : rlfd.rlim_cur; #else return SSH_SYSFDMAX; #endif } static int fdlim_set(int lim) { #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlfd; #endif if (lim <= 0) return (-1); #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); rlfd.rlim_cur = lim; if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); #elif defined (HAVE_SETDTABLESIZE) setdtablesize(lim); #endif return (0); } /* * This is an strsep function that returns a null field for adjacent * separators. This is the same as the 4.4BSD strsep, but different from the * one in the GNU libc. */ static char * xstrsep(char **str, const char *delim) { char *s, *e; if (!**str) return (NULL); s = *str; e = s + strcspn(s, delim); if (*e != '\0') *e++ = '\0'; *str = e; return (s); } /* * Get the next non-null token (like GNU strsep). Strsep() will return a * null token for two adjacent separators, so we may have to loop. */ static char * strnnsep(char **stringp, char *delim) { char *tok; do { tok = xstrsep(stringp, delim); } while (tok && *tok == '\0'); return (tok); } #ifdef WITH_SSH1 static struct sshkey * keygrab_ssh1(con *c) { static struct sshkey *rsa; static struct sshbuf *msg; int r; u_char type; if (rsa == NULL) { if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { error("%s: sshkey_new failed", __func__); return NULL; } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); } if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 || (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */ (r = sshbuf_get_u8(msg, &type)) != 0) goto buf_err; if (type != (int) SSH_SMSG_PUBLIC_KEY) { error("%s: invalid packet type", c->c_name); sshbuf_reset(msg); return NULL; } if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ /* server key */ (r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 || /* host key */ (r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { buf_err: error("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_reset(msg); return NULL; } sshbuf_reset(msg); return (rsa); } #endif static int key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) { con *c; if ((c = ssh_get_app_data(ssh)) != NULL) keyprint(c, hostkey); /* always abort key exchange */ return -1; } static int ssh2_capable(int remote_major, int remote_minor) { switch (remote_major) { case 1: if (remote_minor == 99) return 1; break; case 2: return 1; default: break; } return 0; } static void keygrab_ssh2(con *c) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; int r; enable_compat20(); switch (c->c_keytype) { case KT_DSA: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ssh-dss-cert-v01@openssh.com" : "ssh-dss"; break; case KT_RSA: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa"; break; case KT_ED25519: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ssh-ed25519-cert-v01@openssh.com" : "ssh-ed25519"; break; case KT_ECDSA: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ecdsa-sha2-nistp256-cert-v01@openssh.com," "ecdsa-sha2-nistp384-cert-v01@openssh.com," "ecdsa-sha2-nistp521-cert-v01@openssh.com" : "ecdsa-sha2-nistp256," "ecdsa-sha2-nistp384," "ecdsa-sha2-nistp521"; break; default: fatal("unknown key type %d", c->c_keytype); break; } if ((r = kex_setup(c->c_ssh, myproposal)) != 0) { free(c->c_ssh); fprintf(stderr, "kex_setup: %s\n", ssh_err(r)); exit(1); } #ifdef WITH_OPENSSL c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; # ifdef OPENSSL_HAS_ECC c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif c->c_ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper); /* * do the key-exchange until an error occurs or until * the key_print_wrapper() callback sets c_done. */ ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh); } static void keyprint_one(char *host, struct sshkey *key) { char *hostport; if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL) fatal("host_hash failed"); hostport = put_host_port(host, ssh_port); if (!get_cert) fprintf(stdout, "%s ", hostport); sshkey_write(key, stdout); fputs("\n", stdout); free(hostport); } static void keyprint(con *c, struct sshkey *key) { char *hosts = c->c_output_name ? c->c_output_name : c->c_name; char *host, *ohosts; if (key == NULL) return; if (get_cert || (!hash_hosts && ssh_port == SSH_DEFAULT_PORT)) { keyprint_one(hosts, key); return; } ohosts = hosts = xstrdup(hosts); while ((host = strsep(&hosts, ",")) != NULL) keyprint_one(host, key); free(ohosts); } static int tcpconnect(char *host) { struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, s = -1; snprintf(strport, sizeof strport, "%d", ssh_port); memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { error("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); return -1; } for (ai = aitop; ai; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { error("socket: %s", strerror(errno)); continue; } if (set_nonblock(s) == -1) fatal("%s: set_nonblock(%d)", __func__, s); if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 && errno != EINPROGRESS) error("connect (`%s'): %s", host, strerror(errno)); else break; close(s); s = -1; } freeaddrinfo(aitop); return s; } static int conalloc(char *iname, char *oname, int keytype) { char *namebase, *name, *namelist; int s; namebase = namelist = xstrdup(iname); do { name = xstrsep(&namelist, ","); if (!name) { free(namebase); return (-1); } } while ((s = tcpconnect(name)) < 0); if (s >= maxfd) fatal("conalloc: fdno %d too high", s); if (fdcon[s].c_status) fatal("conalloc: attempt to reuse fdno %d", s); debug3("%s: oname %s kt %d", __func__, oname, keytype); fdcon[s].c_fd = s; fdcon[s].c_status = CS_CON; fdcon[s].c_namebase = namebase; fdcon[s].c_name = name; fdcon[s].c_namelist = namelist; fdcon[s].c_output_name = xstrdup(oname); fdcon[s].c_data = (char *) &fdcon[s].c_plen; fdcon[s].c_len = 4; fdcon[s].c_off = 0; fdcon[s].c_keytype = keytype; gettimeofday(&fdcon[s].c_tv, NULL); fdcon[s].c_tv.tv_sec += timeout; TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); FD_SET(s, read_wait); ncon++; return (s); } static void confree(int s) { if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) fatal("confree: attempt to free bad fdno %d", s); close(s); free(fdcon[s].c_namebase); free(fdcon[s].c_output_name); if (fdcon[s].c_status == CS_KEYS) free(fdcon[s].c_data); fdcon[s].c_status = CS_UNUSED; fdcon[s].c_keytype = 0; if (fdcon[s].c_ssh) { ssh_packet_close(fdcon[s].c_ssh); free(fdcon[s].c_ssh); fdcon[s].c_ssh = NULL; } TAILQ_REMOVE(&tq, &fdcon[s], c_link); FD_CLR(s, read_wait); ncon--; } static void contouch(int s) { TAILQ_REMOVE(&tq, &fdcon[s], c_link); gettimeofday(&fdcon[s].c_tv, NULL); fdcon[s].c_tv.tv_sec += timeout; TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); } static int conrecycle(int s) { con *c = &fdcon[s]; int ret; ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype); confree(s); return (ret); } static void congreet(int s) { int n = 0, remote_major = 0, remote_minor = 0; char buf[256], *cp; char remote_version[sizeof buf]; size_t bufsiz; con *c = &fdcon[s]; for (;;) { memset(buf, '\0', sizeof(buf)); bufsiz = sizeof(buf); cp = buf; while (bufsiz-- && (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') { if (*cp == '\r') *cp = '\n'; cp++; } if (n != 1 || strncmp(buf, "SSH-", 4) == 0) break; } if (n == 0) { switch (errno) { case EPIPE: error("%s: Connection closed by remote host", c->c_name); break; case ECONNREFUSED: break; default: error("read (%s): %s", c->c_name, strerror(errno)); break; } conrecycle(s); return; } if (*cp != '\n' && *cp != '\r') { error("%s: bad greeting", c->c_name); confree(s); return; } *cp = '\0'; if ((c->c_ssh = ssh_packet_set_connection(NULL, s, s)) == NULL) fatal("ssh_packet_set_connection failed"); ssh_packet_set_timeout(c->c_ssh, timeout, 1); ssh_set_app_data(c->c_ssh, c); /* back link */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) == 3) c->c_ssh->compat = compat_datafellows(remote_version); else c->c_ssh->compat = 0; if (c->c_keytype != KT_RSA1) { if (!ssh2_capable(remote_major, remote_minor)) { debug("%s doesn't support ssh2", c->c_name); confree(s); return; } } else if (remote_major != 1) { debug("%s doesn't support ssh1", c->c_name); confree(s); return; } fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf)); n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); if (n < 0 || (size_t)n >= sizeof(buf)) { error("snprintf: buffer too small"); confree(s); return; } if (atomicio(vwrite, s, buf, n) != (size_t)n) { error("write (%s): %s", c->c_name, strerror(errno)); confree(s); return; } if (c->c_keytype != KT_RSA1) { keygrab_ssh2(c); confree(s); return; } c->c_status = CS_SIZE; contouch(s); } static void conread(int s) { con *c = &fdcon[s]; size_t n; if (c->c_status == CS_CON) { congreet(s); return; } n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off); if (n == 0) { error("read (%s): %s", c->c_name, strerror(errno)); confree(s); return; } c->c_off += n; if (c->c_off == c->c_len) switch (c->c_status) { case CS_SIZE: c->c_plen = htonl(c->c_plen); c->c_len = c->c_plen + 8 - (c->c_plen & 7); c->c_off = 0; c->c_data = xmalloc(c->c_len); c->c_status = CS_KEYS; break; #ifdef WITH_SSH1 case CS_KEYS: keyprint(c, keygrab_ssh1(c)); confree(s); return; #endif default: fatal("conread: invalid status %d", c->c_status); break; } contouch(s); } static void conloop(void) { struct timeval seltime, now; fd_set *r, *e; con *c; int i; gettimeofday(&now, NULL); c = TAILQ_FIRST(&tq); if (c && (c->c_tv.tv_sec > now.tv_sec || (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) { seltime = c->c_tv; seltime.tv_sec -= now.tv_sec; seltime.tv_usec -= now.tv_usec; if (seltime.tv_usec < 0) { seltime.tv_usec += 1000000; seltime.tv_sec--; } } else timerclear(&seltime); r = xcalloc(read_wait_nfdset, sizeof(fd_mask)); e = xcalloc(read_wait_nfdset, sizeof(fd_mask)); memcpy(r, read_wait, read_wait_nfdset * sizeof(fd_mask)); memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask)); while (select(maxfd, r, NULL, e, &seltime) == -1 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) ; for (i = 0; i < maxfd; i++) { if (FD_ISSET(i, e)) { error("%s: exception!", fdcon[i].c_name); confree(i); } else if (FD_ISSET(i, r)) conread(i); } free(r); free(e); c = TAILQ_FIRST(&tq); while (c && (c->c_tv.tv_sec < now.tv_sec || (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) { int s = c->c_fd; c = TAILQ_NEXT(c, c_link); conrecycle(s); } } static void do_host(char *host) { char *name = strnnsep(&host, " \t\n"); int j; if (name == NULL) return; for (j = KT_RSA1; j <= KT_ED25519; j *= 2) { if (get_keytypes & j) { while (ncon >= MAXCON) conloop(); conalloc(name, *host ? host : name, j); } } } void fatal(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_FATAL, fmt, args); va_end(args); exit(255); } static void usage(void) { fprintf(stderr, "usage: %s [-46cHv] [-f file] [-p port] [-T timeout] [-t type]\n" "\t\t [host | addrlist namelist] ...\n", __progname); exit(1); } int main(int argc, char **argv) { int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO; int opt, fopt_count = 0, j; char *tname, *cp, line[NI_MAXHOST]; FILE *fp; u_long linenum; extern int optind; extern char *optarg; ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); seed_rng(); TAILQ_INIT(&tq); /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); if (argc <= 1) usage(); while ((opt = getopt(argc, argv, "cHv46p:T:t:f:")) != -1) { switch (opt) { case 'H': hash_hosts = 1; break; case 'c': get_cert = 1; break; case 'p': ssh_port = a2port(optarg); if (ssh_port <= 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(1); } break; case 'T': timeout = convtime(optarg); if (timeout == -1 || timeout == 0) { fprintf(stderr, "Bad timeout '%s'\n", optarg); usage(); } break; case 'v': if (!debug_flag) { debug_flag = 1; log_level = SYSLOG_LEVEL_DEBUG1; } else if (log_level < SYSLOG_LEVEL_DEBUG3) log_level++; else fatal("Too high debugging level."); break; case 'f': if (strcmp(optarg, "-") == 0) optarg = NULL; argv[fopt_count++] = optarg; break; case 't': get_keytypes = 0; tname = strtok(optarg, ","); while (tname) { int type = sshkey_type_from_name(tname); switch (type) { case KEY_RSA1: get_keytypes |= KT_RSA1; break; case KEY_DSA: get_keytypes |= KT_DSA; break; case KEY_ECDSA: get_keytypes |= KT_ECDSA; break; case KEY_RSA: get_keytypes |= KT_RSA; break; case KEY_ED25519: get_keytypes |= KT_ED25519; break; case KEY_UNSPEC: fatal("unknown key type %s", tname); } tname = strtok(NULL, ","); } break; case '4': IPv4or6 = AF_INET; break; case '6': IPv4or6 = AF_INET6; break; case '?': default: usage(); } } if (optind == argc && !fopt_count) usage(); log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1); maxfd = fdlim_get(1); if (maxfd < 0) fatal("%s: fdlim_get: bad value", __progname); if (maxfd > MAXMAXFD) maxfd = MAXMAXFD; if (MAXCON <= 0) fatal("%s: not enough file descriptors", __progname); if (maxfd > fdlim_get(0)) fdlim_set(maxfd); fdcon = xcalloc(maxfd, sizeof(con)); read_wait_nfdset = howmany(maxfd, NFDBITS); read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); for (j = 0; j < fopt_count; j++) { if (argv[j] == NULL) fp = stdin; else if ((fp = fopen(argv[j], "r")) == NULL) fatal("%s: %s: %s", __progname, argv[j], strerror(errno)); linenum = 0; while (read_keyfile_line(fp, argv[j] == NULL ? "(stdin)" : argv[j], line, sizeof(line), &linenum) != -1) { /* Chomp off trailing whitespace and comments */ if ((cp = strchr(line, '#')) == NULL) cp = line + strlen(line) - 1; while (cp >= line) { if (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '#') *cp-- = '\0'; else break; } /* Skip empty lines */ if (*line == '\0') continue; do_host(line); } if (ferror(fp)) fatal("%s: %s: %s", __progname, argv[j], strerror(errno)); fclose(fp); } while (optind < argc) do_host(argv[optind++]); while (ncon > 0) conloop(); return (0); } openssh-7.2p2/ssh-keysign.8010064400017500001750000000057131267006270000140150ustar00djmdjm.\" $OpenBSD: ssh-keysign.8,v 1.15 2016/02/17 07:38:19 jmc Exp $ .\" .\" Copyright (c) 2002 Markus Friedl. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd $Mdocdate: February 17 2016 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME .Nm ssh-keysign .Nd ssh helper program for host-based authentication .Sh SYNOPSIS .Nm .Sh DESCRIPTION .Nm is used by .Xr ssh 1 to access the local host keys and generate the digital signature required during host-based authentication. .Pp .Nm is disabled by default and can only be enabled in the global client configuration file .Pa /etc/ssh/ssh_config by setting .Cm EnableSSHKeysign to .Dq yes . .Pp .Nm is not intended to be invoked by the user, but from .Xr ssh 1 . See .Xr ssh 1 and .Xr sshd 8 for more information about host-based authentication. .Sh FILES .Bl -tag -width Ds -compact .It Pa /etc/ssh/ssh_config Controls whether .Nm is enabled. .Pp .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key .It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They should be owned by root, readable only by root, and not accessible to others. Since they are readable only by root, .Nm must be set-uid root if host-based authentication is used. .Pp .It Pa /etc/ssh/ssh_host_dsa_key-cert.pub .It Pa /etc/ssh/ssh_host_ecdsa_key-cert.pub .It Pa /etc/ssh/ssh_host_ed25519_key-cert.pub .It Pa /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys above. .El .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-keygen 1 , .Xr ssh_config 5 , .Xr sshd 8 .Sh HISTORY .Nm first appeared in .Ox 3.2 . .Sh AUTHORS .An Markus Friedl Aq Mt markus@openbsd.org openssh-7.2p2/ssh-keysign.c010064400017500001750000000206021267006270000140620ustar00djmdjm/* $OpenBSD: ssh-keysign.c,v 1.52 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #ifdef WITH_OPENSSL #include #include #include #endif #include "xmalloc.h" #include "log.h" #include "sshkey.h" #include "ssh.h" #include "ssh2.h" #include "misc.h" #include "sshbuf.h" #include "authfile.h" #include "msg.h" #include "canohost.h" #include "pathnames.h" #include "readconf.h" #include "uidswap.h" #include "sshkey.h" #include "ssherr.h" struct ssh *active_state = NULL; /* XXX needed for linking */ extern char *__progname; /* XXX readconf.c needs these */ uid_t original_real_uid; extern char *__progname; static int valid_request(struct passwd *pw, char *host, struct sshkey **ret, u_char *data, size_t datalen) { struct sshbuf *b; struct sshkey *key = NULL; u_char type, *pkblob; char *p; size_t blen, len; char *pkalg, *luser; int r, pktype, fail; if (ret != NULL) *ret = NULL; fail = 0; if ((b = sshbuf_from(data, datalen)) == NULL) fatal("%s: sshbuf_from failed", __func__); /* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */ if ((r = sshbuf_get_string(b, NULL, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (len != 20 && len != 32) fail++; if ((r = sshbuf_get_u8(b, &type)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (type != SSH2_MSG_USERAUTH_REQUEST) fail++; /* server user */ if ((r = sshbuf_skip_string(b)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* service */ if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("ssh-connection", p) != 0) fail++; free(p); /* method */ if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("hostbased", p) != 0) fail++; free(p); /* pubkey */ if ((r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || (r = sshbuf_get_string(b, &pkblob, &blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); pktype = sshkey_type_from_name(pkalg); if (pktype == KEY_UNSPEC) fail++; else if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { error("%s: bad key blob: %s", __func__, ssh_err(r)); fail++; } else if (key->type != pktype) fail++; free(pkalg); free(pkblob); /* client host name, handle trailing dot */ if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug2("%s: check expect chost %s got %s", __func__, host, p); if (strlen(host) != len - 1) fail++; else if (p[len - 1] != '.') fail++; else if (strncasecmp(host, p, len - 1) != 0) fail++; free(p); /* local user */ if ((r = sshbuf_get_cstring(b, &luser, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp(pw->pw_name, luser) != 0) fail++; free(luser); /* end of message */ if (sshbuf_len(b) != 0) fail++; sshbuf_free(b); debug3("%s: fail %d", __func__, fail); if (fail && key != NULL) sshkey_free(key); else if (ret != NULL) *ret = key; return (fail ? -1 : 0); } int main(int argc, char **argv) { struct sshbuf *b; Options options; #define NUM_KEYTYPES 4 struct sshkey *keys[NUM_KEYTYPES], *key = NULL; struct passwd *pw; int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; u_char *signature, *data, rver; char *host, *fp; size_t slen, dlen; #ifdef WITH_OPENSSL u_int32_t rnd[256]; #endif ssh_malloc_init(); /* must be called before any mallocs */ if (pledge("stdio rpath getpw dns id", NULL) != 0) fatal("%s: pledge: %s", __progname, strerror(errno)); /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) exit(1); /* Leave /dev/null fd iff it is attached to stderr */ if (fd > 2) close(fd); i = 0; /* XXX This really needs to read sshd_config for the paths */ key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_ED25519_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); original_real_uid = getuid(); /* XXX readconf.c needs this */ if ((pw = getpwuid(original_real_uid)) == NULL) fatal("getpwuid failed"); pw = pwcopy(pw); permanently_set_uid(pw); seed_rng(); #ifdef DEBUG_SSH_KEYSIGN log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); #endif /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", _PATH_HOST_CONFIG_FILE); for (i = found = 0; i < NUM_KEYTYPES; i++) { if (key_fd[i] != -1) found = 1; } if (found == 0) fatal("could not open any host key"); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); #endif found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { keys[i] = NULL; if (key_fd[i] == -1) continue; r = sshkey_load_private_type_fd(key_fd[i], KEY_UNSPEC, NULL, &key, NULL); close(key_fd[i]); if (r != 0) debug("parse key %d: %s", i, ssh_err(r)); else if (key != NULL) { keys[i] = key; found = 1; } } if (!found) fatal("no hostkey found"); if (pledge("stdio dns", NULL) != 0) fatal("%s: pledge: %s", __progname, strerror(errno)); if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __progname); if (ssh_msg_recv(STDIN_FILENO, b) < 0) fatal("ssh_msg_recv failed"); if ((r = sshbuf_get_u8(b, &rver)) != 0) fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (rver != version) fatal("bad version: received %d, expected %d", rver, version); if ((r = sshbuf_get_u32(b, (u_int *)&fd)) != 0) fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (fd < 0 || fd == STDIN_FILENO || fd == STDOUT_FILENO) fatal("bad fd"); if ((host = get_local_name(fd)) == NULL) fatal("cannot get local name for fd"); if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); free(host); found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { if (keys[i] != NULL && sshkey_equal_public(key, keys[i])) { found = 1; break; } } if (!found) { if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("%s: sshkey_fingerprint failed", __progname); fatal("no matching hostkey found for key %s %s", sshkey_type(key), fp ? fp : ""); } if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, NULL, 0)) != 0) fatal("sshkey_sign failed: %s", ssh_err(r)); free(data); /* send reply */ sshbuf_reset(b); if ((r = sshbuf_put_string(b, signature, slen)) != 0) fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (ssh_msg_send(STDOUT_FILENO, version, b) == -1) fatal("ssh_msg_send failed"); return (0); } openssh-7.2p2/ssh-pkcs11-client.c010064400017500001750000000123451267006270000147740ustar00djmdjm/* $OpenBSD: ssh-pkcs11-client.c,v 1.6 2015/12/11 00:20:04 mmcc Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifdef ENABLE_PKCS11 #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #include "pathnames.h" #include "xmalloc.h" #include "buffer.h" #include "log.h" #include "misc.h" #include "key.h" #include "authfd.h" #include "atomicio.h" #include "ssh-pkcs11.h" /* borrows code from sftp-server and ssh-agent */ int fd = -1; pid_t pid = -1; static void send_msg(Buffer *m) { u_char buf[4]; int mlen = buffer_len(m); put_u32(buf, mlen); if (atomicio(vwrite, fd, buf, 4) != 4 || atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) != buffer_len(m)) error("write to helper failed"); buffer_consume(m, mlen); } static int recv_msg(Buffer *m) { u_int l, len; u_char buf[1024]; if ((len = atomicio(read, fd, buf, 4)) != 4) { error("read from helper failed: %u", len); return (0); /* XXX */ } len = get_u32(buf); if (len > 256 * 1024) fatal("response too long: %u", len); /* read len bytes into m */ buffer_clear(m); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); if (atomicio(read, fd, buf, l) != l) { error("response from helper failed."); return (0); /* XXX */ } buffer_append(m, buf, l); len -= l; } return (buffer_get_char(m)); } int pkcs11_init(int interactive) { return (0); } void pkcs11_terminate(void) { close(fd); } static int pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) { Key key; u_char *blob, *signature = NULL; u_int blen, slen = 0; int ret = -1; Buffer msg; if (padding != RSA_PKCS1_PADDING) return (-1); key.type = KEY_RSA; key.rsa = rsa; if (key_to_blob(&key, &blob, &blen) == 0) return -1; buffer_init(&msg); buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); buffer_put_string(&msg, blob, blen); buffer_put_string(&msg, from, flen); buffer_put_int(&msg, 0); free(blob); send_msg(&msg); buffer_clear(&msg); if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { signature = buffer_get_string(&msg, &slen); if (slen <= (u_int)RSA_size(rsa)) { memcpy(to, signature, slen); ret = slen; } free(signature); } buffer_free(&msg); return (ret); } /* redirect the private key encrypt operation to the ssh-pkcs11-helper */ static int wrap_key(RSA *rsa) { static RSA_METHOD helper_rsa; memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); helper_rsa.name = "ssh-pkcs11-helper"; helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; RSA_set_method(rsa, &helper_rsa); return (0); } static int pkcs11_start_helper(void) { int pair[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { error("socketpair: %s", strerror(errno)); return (-1); } if ((pid = fork()) == -1) { error("fork: %s", strerror(errno)); return (-1); } else if (pid == 0) { if ((dup2(pair[1], STDIN_FILENO) == -1) || (dup2(pair[1], STDOUT_FILENO) == -1)) { fprintf(stderr, "dup2: %s\n", strerror(errno)); _exit(1); } close(pair[0]); close(pair[1]); execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER, (char *)NULL); fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER, strerror(errno)); _exit(1); } close(pair[1]); fd = pair[0]; return (0); } int pkcs11_add_provider(char *name, char *pin, Key ***keysp) { Key *k; int i, nkeys; u_char *blob; u_int blen; Buffer msg; if (fd < 0 && pkcs11_start_helper() < 0) return (-1); buffer_init(&msg); buffer_put_char(&msg, SSH_AGENTC_ADD_SMARTCARD_KEY); buffer_put_cstring(&msg, name); buffer_put_cstring(&msg, pin); send_msg(&msg); buffer_clear(&msg); if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) { nkeys = buffer_get_int(&msg); *keysp = xcalloc(nkeys, sizeof(Key *)); for (i = 0; i < nkeys; i++) { blob = buffer_get_string(&msg, &blen); free(buffer_get_string(&msg, NULL)); k = key_from_blob(blob, blen); wrap_key(k->rsa); (*keysp)[i] = k; free(blob); } } else { nkeys = -1; } buffer_free(&msg); return (nkeys); } int pkcs11_del_provider(char *name) { int ret = -1; Buffer msg; buffer_init(&msg); buffer_put_char(&msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY); buffer_put_cstring(&msg, name); buffer_put_cstring(&msg, ""); send_msg(&msg); buffer_clear(&msg); if (recv_msg(&msg) == SSH_AGENT_SUCCESS) ret = 0; buffer_free(&msg); return (ret); } #endif /* ENABLE_PKCS11 */ openssh-7.2p2/ssh-pkcs11-helper.8010064400017500001750000000025241267006270000147200ustar00djmdjm.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.4 2013/07/16 00:07:52 schwarze Exp $ .\" .\" Copyright (c) 2010 Markus Friedl. All rights reserved. .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .Dd $Mdocdate: July 16 2013 $ .Dt SSH-PKCS11-HELPER 8 .Os .Sh NAME .Nm ssh-pkcs11-helper .Nd ssh-agent helper program for PKCS#11 support .Sh SYNOPSIS .Nm .Sh DESCRIPTION .Nm is used by .Xr ssh-agent 1 to access keys provided by a PKCS#11 token. .Pp .Nm is not intended to be invoked by the user, but from .Xr ssh-agent 1 . .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 .Sh HISTORY .Nm first appeared in .Ox 4.7 . .Sh AUTHORS .An Markus Friedl Aq Mt markus@openbsd.org openssh-7.2p2/ssh-pkcs11-helper.c010064400017500001750000000177671267006270000150120ustar00djmdjm/* $OpenBSD: ssh-pkcs11-helper.c,v 1.12 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include #ifdef HAVE_SYS_TIME_H # include #endif #include "openbsd-compat/sys-queue.h" #include #include #include #include #include "xmalloc.h" #include "buffer.h" #include "log.h" #include "misc.h" #include "key.h" #include "authfd.h" #include "ssh-pkcs11.h" #ifdef ENABLE_PKCS11 /* borrows code from sftp-server and ssh-agent */ struct pkcs11_keyinfo { Key *key; char *providername; TAILQ_ENTRY(pkcs11_keyinfo) next; }; TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; #define MAX_MSG_LENGTH 10240 /*XXX*/ /* helper */ #define get_int() buffer_get_int(&iqueue); #define get_string(lenp) buffer_get_string(&iqueue, lenp); /* input and output queue */ Buffer iqueue; Buffer oqueue; static void add_key(Key *k, char *name) { struct pkcs11_keyinfo *ki; ki = xcalloc(1, sizeof(*ki)); ki->providername = xstrdup(name); ki->key = k; TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next); } static void del_keys_by_name(char *name) { struct pkcs11_keyinfo *ki, *nxt; for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) { nxt = TAILQ_NEXT(ki, next); if (!strcmp(ki->providername, name)) { TAILQ_REMOVE(&pkcs11_keylist, ki, next); free(ki->providername); key_free(ki->key); free(ki); } } } /* lookup matching 'private' key */ static Key * lookup_key(Key *k) { struct pkcs11_keyinfo *ki; TAILQ_FOREACH(ki, &pkcs11_keylist, next) { debug("check %p %s", ki, ki->providername); if (key_equal(k, ki->key)) return (ki->key); } return (NULL); } static void send_msg(Buffer *m) { int mlen = buffer_len(m); buffer_put_int(&oqueue, mlen); buffer_append(&oqueue, buffer_ptr(m), mlen); buffer_consume(m, mlen); } static void process_add(void) { char *name, *pin; Key **keys; int i, nkeys; u_char *blob; u_int blen; Buffer msg; buffer_init(&msg); name = get_string(NULL); pin = get_string(NULL); if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) { buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER); buffer_put_int(&msg, nkeys); for (i = 0; i < nkeys; i++) { if (key_to_blob(keys[i], &blob, &blen) == 0) continue; buffer_put_string(&msg, blob, blen); buffer_put_cstring(&msg, name); free(blob); add_key(keys[i], name); } free(keys); } else { buffer_put_char(&msg, SSH_AGENT_FAILURE); } free(pin); free(name); send_msg(&msg); buffer_free(&msg); } static void process_del(void) { char *name, *pin; Buffer msg; buffer_init(&msg); name = get_string(NULL); pin = get_string(NULL); del_keys_by_name(name); if (pkcs11_del_provider(name) == 0) buffer_put_char(&msg, SSH_AGENT_SUCCESS); else buffer_put_char(&msg, SSH_AGENT_FAILURE); free(pin); free(name); send_msg(&msg); buffer_free(&msg); } static void process_sign(void) { u_char *blob, *data, *signature = NULL; u_int blen, dlen, slen = 0; int ok = -1; Key *key, *found; Buffer msg; blob = get_string(&blen); data = get_string(&dlen); (void)get_int(); /* XXX ignore flags */ if ((key = key_from_blob(blob, blen)) != NULL) { if ((found = lookup_key(key)) != NULL) { #ifdef WITH_OPENSSL int ret; slen = RSA_size(key->rsa); signature = xmalloc(slen); if ((ret = RSA_private_encrypt(dlen, data, signature, found->rsa, RSA_PKCS1_PADDING)) != -1) { slen = ret; ok = 0; } #endif /* WITH_OPENSSL */ } key_free(key); } buffer_init(&msg); if (ok == 0) { buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); buffer_put_string(&msg, signature, slen); } else { buffer_put_char(&msg, SSH_AGENT_FAILURE); } free(data); free(blob); free(signature); send_msg(&msg); buffer_free(&msg); } static void process(void) { u_int msg_len; u_int buf_len; u_int consumed; u_int type; u_char *cp; buf_len = buffer_len(&iqueue); if (buf_len < 5) return; /* Incomplete message. */ cp = buffer_ptr(&iqueue); msg_len = get_u32(cp); if (msg_len > MAX_MSG_LENGTH) { error("bad message len %d", msg_len); cleanup_exit(11); } if (buf_len < msg_len + 4) return; buffer_consume(&iqueue, 4); buf_len -= 4; type = buffer_get_char(&iqueue); switch (type) { case SSH_AGENTC_ADD_SMARTCARD_KEY: debug("process_add"); process_add(); break; case SSH_AGENTC_REMOVE_SMARTCARD_KEY: debug("process_del"); process_del(); break; case SSH2_AGENTC_SIGN_REQUEST: debug("process_sign"); process_sign(); break; default: error("Unknown message %d", type); break; } /* discard the remaining bytes from the current packet */ if (buf_len < buffer_len(&iqueue)) { error("iqueue grew unexpectedly"); cleanup_exit(255); } consumed = buf_len - buffer_len(&iqueue); if (msg_len < consumed) { error("msg_len %d < consumed %d", msg_len, consumed); cleanup_exit(255); } if (msg_len > consumed) buffer_consume(&iqueue, msg_len - consumed); } void cleanup_exit(int i) { /* XXX */ _exit(i); } int main(int argc, char **argv) { fd_set *rset, *wset; int in, out, max, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; LogLevel log_level = SYSLOG_LEVEL_ERROR; char buf[4*4096]; extern char *__progname; ssh_malloc_init(); /* must be called before any mallocs */ TAILQ_INIT(&pkcs11_keylist); pkcs11_init(0); seed_rng(); __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); in = STDIN_FILENO; out = STDOUT_FILENO; max = 0; if (in > max) max = in; if (out > max) max = out; buffer_init(&iqueue); buffer_init(&oqueue); set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); rset = xmalloc(set_size); wset = xmalloc(set_size); for (;;) { memset(rset, 0, set_size); memset(wset, 0, set_size); /* * Ensure that we can read a full buffer and handle * the worst-case length packet it can generate, * otherwise apply backpressure by stopping reads. */ if (buffer_check_alloc(&iqueue, sizeof(buf)) && buffer_check_alloc(&oqueue, MAX_MSG_LENGTH)) FD_SET(in, rset); olen = buffer_len(&oqueue); if (olen > 0) FD_SET(out, wset); if (select(max+1, rset, wset, NULL, NULL) < 0) { if (errno == EINTR) continue; error("select: %s", strerror(errno)); cleanup_exit(2); } /* copy stdin to iqueue */ if (FD_ISSET(in, rset)) { len = read(in, buf, sizeof buf); if (len == 0) { debug("read eof"); cleanup_exit(0); } else if (len < 0) { error("read: %s", strerror(errno)); cleanup_exit(1); } else { buffer_append(&iqueue, buf, len); } } /* send oqueue to stdout */ if (FD_ISSET(out, wset)) { len = write(out, buffer_ptr(&oqueue), olen); if (len < 0) { error("write: %s", strerror(errno)); cleanup_exit(1); } else { buffer_consume(&oqueue, len); } } /* * Process requests from client if we can fit the results * into the output buffer, otherwise stop processing input * and let the output queue drain. */ if (buffer_check_alloc(&oqueue, MAX_MSG_LENGTH)) process(); } } #else /* ENABLE_PKCS11 */ int main(int argc, char **argv) { extern char *__progname; __progname = ssh_get_progname(argv[0]); log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0); fatal("PKCS#11 support disabled at compile time"); } #endif /* ENABLE_PKCS11 */ openssh-7.2p2/ssh-pkcs11.c010064400017500001750000000445211267006270000135210ustar00djmdjm/* $OpenBSD: ssh-pkcs11.c,v 1.22 2016/02/12 00:20:30 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifdef ENABLE_PKCS11 #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include "openbsd-compat/sys-queue.h" #include #define CRYPTOKI_COMPAT #include "pkcs11.h" #include "log.h" #include "misc.h" #include "sshkey.h" #include "ssh-pkcs11.h" #include "xmalloc.h" struct pkcs11_slotinfo { CK_TOKEN_INFO token; CK_SESSION_HANDLE session; int logged_in; }; struct pkcs11_provider { char *name; void *handle; CK_FUNCTION_LIST *function_list; CK_INFO info; CK_ULONG nslots; CK_SLOT_ID *slotlist; struct pkcs11_slotinfo *slotinfo; int valid; int refcount; TAILQ_ENTRY(pkcs11_provider) next; }; TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; struct pkcs11_key { struct pkcs11_provider *provider; CK_ULONG slotidx; int (*orig_finish)(RSA *rsa); RSA_METHOD rsa_method; char *keyid; int keyid_len; }; int pkcs11_interactive = 0; int pkcs11_init(int interactive) { pkcs11_interactive = interactive; TAILQ_INIT(&pkcs11_providers); return (0); } /* * finalize a provider shared libarary, it's no longer usable. * however, there might still be keys referencing this provider, * so the actuall freeing of memory is handled by pkcs11_provider_unref(). * this is called when a provider gets unregistered. */ static void pkcs11_provider_finalize(struct pkcs11_provider *p) { CK_RV rv; CK_ULONG i; debug("pkcs11_provider_finalize: %p refcount %d valid %d", p, p->refcount, p->valid); if (!p->valid) return; for (i = 0; i < p->nslots; i++) { if (p->slotinfo[i].session && (rv = p->function_list->C_CloseSession( p->slotinfo[i].session)) != CKR_OK) error("C_CloseSession failed: %lu", rv); } if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) error("C_Finalize failed: %lu", rv); p->valid = 0; p->function_list = NULL; dlclose(p->handle); } /* * remove a reference to the provider. * called when a key gets destroyed or when the provider is unregistered. */ static void pkcs11_provider_unref(struct pkcs11_provider *p) { debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); if (--p->refcount <= 0) { if (p->valid) error("pkcs11_provider_unref: %p still valid", p); free(p->slotlist); free(p->slotinfo); free(p); } } /* unregister all providers, keys might still point to the providers */ void pkcs11_terminate(void) { struct pkcs11_provider *p; while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); pkcs11_provider_finalize(p); pkcs11_provider_unref(p); } } /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) { struct pkcs11_provider *p; TAILQ_FOREACH(p, &pkcs11_providers, next) { debug("check %p %s", p, p->name); if (!strcmp(provider_id, p->name)) return (p); } return (NULL); } /* unregister provider by name */ int pkcs11_del_provider(char *provider_id) { struct pkcs11_provider *p; if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); pkcs11_provider_finalize(p); pkcs11_provider_unref(p); return (0); } return (-1); } /* openssl callback for freeing an RSA key */ static int pkcs11_rsa_finish(RSA *rsa) { struct pkcs11_key *k11; int rv = -1; if ((k11 = RSA_get_app_data(rsa)) != NULL) { if (k11->orig_finish) rv = k11->orig_finish(rsa); if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); free(k11); } return (rv); } /* find a single 'obj' for given attributes */ static int pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, CK_ULONG nattr, CK_OBJECT_HANDLE *obj) { CK_FUNCTION_LIST *f; CK_SESSION_HANDLE session; CK_ULONG nfound = 0; CK_RV rv; int ret = -1; f = p->function_list; session = p->slotinfo[slotidx].session; if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); } if ((rv = f->C_FindObjects(session, obj, 1, &nfound)) != CKR_OK || nfound != 1) { debug("C_FindObjects failed (nfound %lu nattr %lu): %lu", nfound, nattr, rv); } else ret = 0; if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) error("C_FindObjectsFinal failed: %lu", rv); return (ret); } /* openssl callback doing the actual signing operation */ static int pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) { struct pkcs11_key *k11; struct pkcs11_slotinfo *si; CK_FUNCTION_LIST *f; CK_OBJECT_HANDLE obj; CK_ULONG tlen = 0; CK_RV rv; CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; CK_BBOOL true_val = CK_TRUE; CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 }; CK_ATTRIBUTE key_filter[] = { {CKA_CLASS, NULL, sizeof(private_key_class) }, {CKA_ID, NULL, 0}, {CKA_SIGN, NULL, sizeof(true_val) } }; char *pin = NULL, prompt[1024]; int rval = -1; key_filter[0].pValue = &private_key_class; key_filter[2].pValue = &true_val; if ((k11 = RSA_get_app_data(rsa)) == NULL) { error("RSA_get_app_data failed for rsa %p", rsa); return (-1); } if (!k11->provider || !k11->provider->valid) { error("no pkcs11 (valid) provider for rsa %p", rsa); return (-1); } f = k11->provider->function_list; si = &k11->provider->slotinfo[k11->slotidx]; if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (!pkcs11_interactive) { error("need pin entry%s", (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? " on reader keypad" : ""); return (-1); } if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) verbose("Deferring PIN entry to reader keypad."); else { snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", si->token.label); pin = read_passphrase(prompt, RP_ALLOW_EOF); if (pin == NULL) return (-1); /* bail out */ } rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) { explicit_bzero(pin, strlen(pin)); free(pin); } if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { error("C_Login failed: %lu", rv); return (-1); } si->logged_in = 1; } key_filter[1].pValue = k11->keyid; key_filter[1].ulValueLen = k11->keyid_len; /* try to find object w/CKA_SIGN first, retry w/o */ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 && pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) { error("cannot find private key"); } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { error("C_SignInit failed: %lu", rv); } else { /* XXX handle CKR_BUFFER_TOO_SMALL */ tlen = RSA_size(rsa); rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen); if (rv == CKR_OK) rval = tlen; else error("C_Sign failed: %lu", rv); } return (rval); } static int pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) { return (-1); } /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, CK_ATTRIBUTE *keyid_attrib, RSA *rsa) { struct pkcs11_key *k11; const RSA_METHOD *def = RSA_get_default_method(); k11 = xcalloc(1, sizeof(*k11)); k11->provider = provider; provider->refcount++; /* provider referenced by RSA key */ k11->slotidx = slotidx; /* identify key object on smartcard */ k11->keyid_len = keyid_attrib->ulValueLen; if (k11->keyid_len > 0) { k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } k11->orig_finish = def->finish; memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); k11->rsa_method.name = "pkcs11"; k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; k11->rsa_method.finish = pkcs11_rsa_finish; RSA_set_method(rsa, &k11->rsa_method); RSA_set_app_data(rsa, k11); return (0); } /* remove trailing spaces */ static void rmspace(u_char *buf, size_t len) { size_t i; if (!len) return; for (i = len - 1; i > 0; i--) if (i == len - 1 || buf[i] == ' ') buf[i] = '\0'; else break; } /* * open a pkcs11 session and login if required. * if pin == NULL we delay login until key use */ static int pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) { CK_RV rv; CK_FUNCTION_LIST *f; CK_SESSION_HANDLE session; int login_required; f = p->function_list; login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; if (pin && login_required && !strlen(pin)) { error("pin required"); return (-1); } if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { error("C_OpenSession failed: %lu", rv); return (-1); } if (login_required && pin) { rv = f->C_Login(session, CKU_USER, (u_char *)pin, strlen(pin)); if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { error("C_Login failed: %lu", rv); if ((rv = f->C_CloseSession(session)) != CKR_OK) error("C_CloseSession failed: %lu", rv); return (-1); } p->slotinfo[slotidx].logged_in = 1; } p->slotinfo[slotidx].session = session; return (0); } /* * lookup public keys for token in slot identified by slotidx, * add 'wrapped' public keys to the 'keysp' array and increment nkeys. * keysp points to an (possibly empty) array with *nkeys keys. */ static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, struct sshkey ***keysp, int *nkeys) { CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; CK_ATTRIBUTE pubkey_filter[] = { { CKA_CLASS, NULL, sizeof(pubkey_class) } }; CK_ATTRIBUTE cert_filter[] = { { CKA_CLASS, NULL, sizeof(cert_class) } }; CK_ATTRIBUTE pubkey_attribs[] = { { CKA_ID, NULL, 0 }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 } }; CK_ATTRIBUTE cert_attribs[] = { { CKA_ID, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; pubkey_filter[0].pValue = &pubkey_class; cert_filter[0].pValue = &cert_class; if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, keysp, nkeys) < 0 || pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, keysp, nkeys) < 0) return (-1); return (0); } static int pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) { int i; for (i = 0; i < *nkeys; i++) if (sshkey_equal(key, (*keysp)[i])) return (1); return (0); } static int pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], struct sshkey ***keysp, int *nkeys) { struct sshkey *key; RSA *rsa; X509 *x509; EVP_PKEY *evp; int i; const u_char *cp; CK_RV rv; CK_OBJECT_HANDLE obj; CK_ULONG nfound; CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f; f = p->function_list; session = p->slotinfo[slotidx].session; /* setup a filter the looks for public keys */ if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); return (-1); } while (1) { /* XXX 3 attributes in attribs[] */ for (i = 0; i < 3; i++) { attribs[i].pValue = NULL; attribs[i].ulValueLen = 0; } if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK || nfound == 0) break; /* found a key, so figure out size of the attributes */ if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); continue; } /* * Allow CKA_ID (always first attribute) to be empty, but * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ if (attribs[1].ulValueLen == 0 || attribs[2].ulValueLen == 0) { continue; } /* allocate buffers for attributes */ for (i = 0; i < 3; i++) { if (attribs[i].ulValueLen > 0) { attribs[i].pValue = xmalloc( attribs[i].ulValueLen); } } /* * retrieve ID, modulus and public exponent of RSA key, * or ID, subject and value for certificates. */ rsa = NULL; if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); } else if (attribs[1].type == CKA_MODULUS ) { if ((rsa = RSA_new()) == NULL) { error("RSA_new failed"); } else { rsa->n = BN_bin2bn(attribs[1].pValue, attribs[1].ulValueLen, NULL); rsa->e = BN_bin2bn(attribs[2].pValue, attribs[2].ulValueLen, NULL); } } else { cp = attribs[2].pValue; if ((x509 = X509_new()) == NULL) { error("X509_new failed"); } else if (d2i_X509(&x509, &cp, attribs[2].ulValueLen) == NULL) { error("d2i_X509 failed"); } else if ((evp = X509_get_pubkey(x509)) == NULL || evp->type != EVP_PKEY_RSA || evp->pkey.rsa == NULL) { debug("X509_get_pubkey failed or no rsa"); } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) == NULL) { error("RSAPublicKey_dup"); } if (x509) X509_free(x509); } if (rsa && rsa->n && rsa->e && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { key = sshkey_new(KEY_UNSPEC); key->rsa = rsa; key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; if (pkcs11_key_included(keysp, nkeys, key)) { sshkey_free(key); } else { /* expand key array and add key */ *keysp = xreallocarray(*keysp, *nkeys + 1, sizeof(struct sshkey *)); (*keysp)[*nkeys] = key; *nkeys = *nkeys + 1; debug("have %d keys", *nkeys); } } else if (rsa) { RSA_free(rsa); } for (i = 0; i < 3; i++) free(attribs[i].pValue); } if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) error("C_FindObjectsFinal failed: %lu", rv); return (0); } /* register a new provider, fails if provider already exists */ int pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { int nkeys, need_finalize = 0; struct pkcs11_provider *p = NULL; void *handle = NULL; CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); CK_RV rv; CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; *keyp = NULL; if (pkcs11_provider_lookup(provider_id) != NULL) { error("provider already registered: %s", provider_id); goto fail; } /* open shared pkcs11-libarary */ if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { error("dlopen %s failed: %s", provider_id, dlerror()); goto fail; } if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { error("dlsym(C_GetFunctionList) failed: %s", dlerror()); goto fail; } p = xcalloc(1, sizeof(*p)); p->name = xstrdup(provider_id); p->handle = handle; /* setup the pkcs11 callbacks */ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { error("C_GetFunctionList failed: %lu", rv); goto fail; } p->function_list = f; if ((rv = f->C_Initialize(NULL)) != CKR_OK) { error("C_Initialize failed: %lu", rv); goto fail; } need_finalize = 1; if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { error("C_GetInfo failed: %lu", rv); goto fail; } rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); debug("manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", p->info.manufacturerID, p->info.cryptokiVersion.major, p->info.cryptokiVersion.minor, p->info.libraryDescription, p->info.libraryVersion.major, p->info.libraryVersion.minor); if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { error("C_GetSlotList failed: %lu", rv); goto fail; } if (p->nslots == 0) { error("no slots"); goto fail; } p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) != CKR_OK) { error("C_GetSlotList failed: %lu", rv); goto fail; } p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); p->valid = 1; nkeys = 0; for (i = 0; i < p->nslots; i++) { token = &p->slotinfo[i].token; if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) != CKR_OK) { error("C_GetTokenInfo failed: %lu", rv); continue; } if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { debug2("%s: ignoring uninitialised token in slot %lu", __func__, (unsigned long)i); continue; } rmspace(token->label, sizeof(token->label)); rmspace(token->manufacturerID, sizeof(token->manufacturerID)); rmspace(token->model, sizeof(token->model)); rmspace(token->serialNumber, sizeof(token->serialNumber)); debug("label <%s> manufacturerID <%s> model <%s> serial <%s>" " flags 0x%lx", token->label, token->manufacturerID, token->model, token->serialNumber, token->flags); /* open session, login with pin and retrieve public keys */ if (pkcs11_open_session(p, i, pin) == 0) pkcs11_fetch_keys(p, i, keyp, &nkeys); } if (nkeys > 0) { TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); p->refcount++; /* add to provider list */ return (nkeys); } error("no keys"); /* don't add the provider, since it does not have any keys */ fail: if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) error("C_Finalize failed: %lu", rv); if (p) { free(p->slotlist); free(p->slotinfo); free(p); } if (handle) dlclose(handle); return (-1); } #else int pkcs11_init(int interactive) { return (0); } void pkcs11_terminate(void) { return; } #endif /* ENABLE_PKCS11 */ openssh-7.2p2/ssh-pkcs11.h010064400017500001750000000020761267006270000135250ustar00djmdjm/* $OpenBSD: ssh-pkcs11.h,v 1.4 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ int pkcs11_init(int); void pkcs11_terminate(void); int pkcs11_add_provider(char *, char *, struct sshkey ***); int pkcs11_del_provider(char *); #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) #undef ENABLE_PKCS11 #endif openssh-7.2p2/ssh-rsa.c010064400017500001750000000224321267006270000132010ustar00djmdjm/* $OpenBSD: ssh-rsa.c,v 1.58 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * * 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" #ifdef WITH_OPENSSL #include #include #include #include #include #include "sshbuf.h" #include "compat.h" #include "ssherr.h" #define SSHKEY_INTERNAL #include "sshkey.h" #include "digest.h" static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); static const char * rsa_hash_alg_ident(int hash_alg) { switch (hash_alg) { case SSH_DIGEST_SHA1: return "ssh-rsa"; case SSH_DIGEST_SHA256: return "rsa-sha2-256"; case SSH_DIGEST_SHA512: return "rsa-sha2-512"; } return NULL; } static int rsa_hash_alg_from_ident(const char *ident) { if (strcmp(ident, "ssh-rsa") == 0) return SSH_DIGEST_SHA1; if (strcmp(ident, "rsa-sha2-256") == 0) return SSH_DIGEST_SHA256; if (strcmp(ident, "rsa-sha2-512") == 0) return SSH_DIGEST_SHA512; return -1; } static int rsa_hash_alg_nid(int type) { switch (type) { case SSH_DIGEST_SHA1: return NID_sha1; case SSH_DIGEST_SHA256: return NID_sha256; case SSH_DIGEST_SHA512: return NID_sha512; default: return -1; } } /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *alg_ident) { u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; size_t slen; u_int dlen, len; int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; if (alg_ident == NULL || strlen(alg_ident) == 0 || strncmp(alg_ident, "ssh-rsa-cert", strlen("ssh-rsa-cert")) == 0) hash_alg = SSH_DIGEST_SHA1; else hash_alg = rsa_hash_alg_from_ident(alg_ident); if (key == NULL || key->rsa == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA || BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_INVALID_ARGUMENT; slen = RSA_size(key->rsa); if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; /* hash the data */ nid = rsa_hash_alg_nid(hash_alg); if ((dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; if ((sig = malloc(slen)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (len < slen) { size_t diff = slen - len; memmove(sig + diff, sig, len); explicit_bzero(sig, diff); } else if (len > slen) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } /* encode signature */ if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 || (ret = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*sigp, sshbuf_ptr(b), len); } if (lenp != NULL) *lenp = len; ret = 0; out: explicit_bzero(digest, sizeof(digest)); if (sig != NULL) { explicit_bzero(sig, slen); free(sig); } sshbuf_free(b); return ret; } int ssh_rsa_verify(const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t datalen) { char *ktype = NULL; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; size_t len, diff, modlen, dlen; struct sshbuf *b = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; if (key == NULL || key->rsa == NULL || sshkey_type_plain(key->type) != KEY_RSA || BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_INVALID_ARGUMENT; if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if ((hash_alg = rsa_hash_alg_from_ident(ktype)) == -1) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } if (sshbuf_get_string(b, &sigblob, &len) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (sshbuf_len(b) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; } /* RSA_verify expects a signature of RSA_size */ modlen = RSA_size(key->rsa); if (len > modlen) { ret = SSH_ERR_KEY_BITS_MISMATCH; goto out; } else if (len < modlen) { diff = modlen - len; osigblob = sigblob; if ((sigblob = realloc(sigblob, modlen)) == NULL) { sigblob = osigblob; /* put it back for clear/free */ ret = SSH_ERR_ALLOC_FAIL; goto out; } memmove(sigblob + diff, sigblob, len); explicit_bzero(sigblob, diff); len = modlen; } if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } if ((ret = ssh_digest_memory(hash_alg, data, datalen, digest, sizeof(digest))) != 0) goto out; ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, key->rsa); out: if (sigblob != NULL) { explicit_bzero(sigblob, len); free(sigblob); } free(ktype); sshbuf_free(b); explicit_bzero(digest, sizeof(digest)); return ret; } /* * See: * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn */ /* * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) * oiw(14) secsig(3) algorithms(2) 26 } */ static const u_char id_sha1[] = { 0x30, 0x21, /* type Sequence, length 0x21 (33) */ 0x30, 0x09, /* type Sequence, length 0x09 */ 0x06, 0x05, /* type OID, length 0x05 */ 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ 0x05, 0x00, /* NULL */ 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ }; /* * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) * id-sha256(1) } */ static const u_char id_sha256[] = { 0x30, 0x31, /* type Sequence, length 0x31 (49) */ 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ 0x06, 0x09, /* type OID, length 0x09 */ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ 0x05, 0x00, /* NULL */ 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ }; /* * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) * id-sha256(3) } */ static const u_char id_sha512[] = { 0x30, 0x51, /* type Sequence, length 0x51 (81) */ 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ 0x06, 0x09, /* type OID, length 0x09 */ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ 0x05, 0x00, /* NULL */ 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ }; static int rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) { switch (hash_alg) { case SSH_DIGEST_SHA1: *oidp = id_sha1; *oidlenp = sizeof(id_sha1); break; case SSH_DIGEST_SHA256: *oidp = id_sha256; *oidlenp = sizeof(id_sha256); break; case SSH_DIGEST_SHA512: *oidp = id_sha512; *oidlenp = sizeof(id_sha512); break; default: return SSH_ERR_INVALID_ARGUMENT; } return 0; } static int openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, u_char *sigbuf, size_t siglen, RSA *rsa) { size_t rsasize = 0, oidlen = 0, hlen = 0; int ret, len, oidmatch, hashmatch; const u_char *oid = NULL; u_char *decrypted = NULL; if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0) return ret; ret = SSH_ERR_INTERNAL_ERROR; hlen = ssh_digest_bytes(hash_alg); if (hashlen != hlen) { ret = SSH_ERR_INVALID_ARGUMENT; goto done; } rsasize = RSA_size(rsa); if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || siglen == 0 || siglen > rsasize) { ret = SSH_ERR_INVALID_ARGUMENT; goto done; } if ((decrypted = malloc(rsasize)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto done; } if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, RSA_PKCS1_PADDING)) < 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto done; } if (len < 0 || (size_t)len != hlen + oidlen) { ret = SSH_ERR_INVALID_FORMAT; goto done; } oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0; hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0; if (!oidmatch || !hashmatch) { ret = SSH_ERR_SIGNATURE_INVALID; goto done; } ret = 0; done: if (decrypted) { explicit_bzero(decrypted, rsasize); free(decrypted); } return ret; } #endif /* WITH_OPENSSL */ openssh-7.2p2/ssh-sandbox.h010064400017500001750000000021301267006270000140500ustar00djmdjm/* $OpenBSD: ssh-sandbox.h,v 1.1 2011/06/23 09:34:13 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ struct monitor; struct ssh_sandbox; struct ssh_sandbox *ssh_sandbox_init(struct monitor *); void ssh_sandbox_child(struct ssh_sandbox *); void ssh_sandbox_parent_finish(struct ssh_sandbox *); void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); openssh-7.2p2/ssh.1010064400017500001750000001265031267006270000123400ustar00djmdjm.\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $OpenBSD: ssh.1,v 1.369 2016/02/17 07:38:19 jmc Exp $ .Dd $Mdocdate: February 17 2016 $ .Dt SSH 1 .Os .Sh NAME .Nm ssh .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh .Bk -words .Op Fl 1246AaCfGgKkMNnqsTtVvXxYy .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl D Oo Ar bind_address : Oc Ns Ar port .Op Fl E Ar log_file .Op Fl e Ar escape_char .Op Fl F Ar configfile .Op Fl I Ar pkcs11 .Op Fl i Ar identity_file .Op Fl L Ar address .Op Fl l Ar login_name .Op Fl m Ar mac_spec .Op Fl O Ar ctl_cmd .Op Fl o Ar option .Op Fl p Ar port .Op Fl Q Ar query_option .Op Fl R Ar address .Op Fl S Ar ctl_path .Op Fl W Ar host : Ns Ar port .Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Ek .Sh DESCRIPTION .Nm (SSH client) is a program for logging into a remote machine and for executing commands on a remote machine. It is intended to provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections, arbitrary TCP ports and .Ux Ns -domain sockets can also be forwarded over the secure channel. .Pp .Nm connects and logs into the specified .Ar hostname (with optional .Ar user name). The user must prove his/her identity to the remote machine using one of several methods (see below). .Pp If .Ar command is specified, it is executed on the remote host instead of a login shell. .Pp The options are as follows: .Pp .Bl -tag -width Ds -compact .It Fl 1 Forces .Nm to try protocol version 1 only. .Pp .It Fl 2 Forces .Nm to try protocol version 2 only. .Pp .It Fl 4 Forces .Nm to use IPv4 addresses only. .Pp .It Fl 6 Forces .Nm to use IPv6 addresses only. .Pp .It Fl A Enables forwarding of the authentication agent connection. This can also be specified on a per-host basis in a configuration file. .Pp Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's .Ux Ns -domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. .Pp .It Fl a Disables forwarding of the authentication agent connection. .Pp .It Fl b Ar bind_address Use .Ar bind_address on the local machine as the source address of the connection. Only useful on systems with more than one address. .Pp .It Fl C Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11, TCP and .Ux Ns -domain connections). The compression algorithm is the same used by .Xr gzip 1 , and the .Dq level can be controlled by the .Cm CompressionLevel option for protocol version 1. Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks. The default value can be set on a host-by-host basis in the configuration files; see the .Cm Compression option. .Pp .It Fl c Ar cipher_spec Selects the cipher specification for encrypting the session. .Pp Protocol version 1 allows specification of a single cipher. The supported values are .Dq 3des , .Dq blowfish , and .Dq des . For protocol version 2, .Ar cipher_spec is a comma-separated list of ciphers listed in order of preference. See the .Cm Ciphers keyword in .Xr ssh_config 5 for more information. .Pp .It Fl D Xo .Sm off .Oo Ar bind_address : Oc .Ar port .Sm on .Xc Specifies a local .Dq dynamic application-level port forwarding. This works by allocating a socket to listen to .Ar port on the local side, optionally bound to the specified .Ar bind_address . Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and .Nm will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. .Pp IPv6 addresses can be specified by enclosing the address in square brackets. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the .Cm GatewayPorts setting. However, an explicit .Ar bind_address may be used to bind the connection to a specific address. The .Ar bind_address of .Dq localhost indicates that the listening port be bound for local use only, while an empty address or .Sq * indicates that the port should be available from all interfaces. .Pp .It Fl E Ar log_file Append debug logs to .Ar log_file instead of standard error. .Pp .It Fl e Ar escape_char Sets the escape character for sessions with a pty (default: .Ql ~ ) . The escape character is only recognized at the beginning of a line. The escape character followed by a dot .Pq Ql \&. closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once. Setting the character to .Dq none disables any escapes and makes the session fully transparent. .Pp .It Fl F Ar configfile Specifies an alternative per-user configuration file. If a configuration file is given on the command line, the system-wide configuration file .Pq Pa /etc/ssh/ssh_config will be ignored. The default for the per-user configuration file is .Pa ~/.ssh/config . .Pp .It Fl f Requests .Nm to go to background just before command execution. This is useful if .Nm is going to ask for passwords or passphrases, but the user wants it in the background. This implies .Fl n . The recommended way to start X11 programs at a remote site is with something like .Ic ssh -f host xterm . .Pp If the .Cm ExitOnForwardFailure configuration option is set to .Dq yes , then a client started with .Fl f will wait for all remote port forwards to be successfully established before placing itself in the background. .Pp .It Fl G Causes .Nm to print its configuration after evaluating .Cm Host and .Cm Match blocks and exit. .Pp .It Fl g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified on the master process. .Pp .It Fl I Ar pkcs11 Specify the PKCS#11 shared library .Nm should use to communicate with a PKCS#11 token providing the user's private RSA key. .Pp .It Fl i Ar identity_file Selects a file from which the identity (private key) for public key authentication is read. The default is .Pa ~/.ssh/identity for protocol version 1, and .Pa ~/.ssh/id_dsa , .Pa ~/.ssh/id_ecdsa , .Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/id_rsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple .Fl i options (and multiple identities specified in configuration files). If no certificates have been explicitly specified by the .Cm CertificateFile directive, .Nm will also try to load certificate information from the filename obtained by appending .Pa -cert.pub to identity filenames. .Pp .It Fl K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. .Pp .It Fl k Disables forwarding (delegation) of GSSAPI credentials to the server. .Pp .It Fl L Xo .Sm off .Oo Ar bind_address : Oc .Ar port : host : hostport .Sm on .Xc .It Fl L Xo .Sm off .Oo Ar bind_address : Oc .Ar port : remote_socket .Sm on .Xc .It Fl L Xo .Sm off .Ar local_socket : host : hostport .Sm on .Xc .It Fl L Xo .Sm off .Ar local_socket : remote_socket .Sm on .Xc Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side. This works by allocating a socket to listen to either a TCP .Ar port on the local side, optionally bound to the specified .Ar bind_address , or to a Unix socket. Whenever a connection is made to the local port or socket, the connection is forwarded over the secure channel, and a connection is made to either .Ar host port .Ar hostport , or the Unix socket .Ar remote_socket , from the remote machine. .Pp Port forwardings can also be specified in the configuration file. Only the superuser can forward privileged ports. IPv6 addresses can be specified by enclosing the address in square brackets. .Pp By default, the local port is bound in accordance with the .Cm GatewayPorts setting. However, an explicit .Ar bind_address may be used to bind the connection to a specific address. The .Ar bind_address of .Dq localhost indicates that the listening port be bound for local use only, while an empty address or .Sq * indicates that the port should be available from all interfaces. .Pp .It Fl l Ar login_name Specifies the user to log in as on the remote machine. This also may be specified on a per-host basis in the configuration file. .Pp .It Fl M Places the .Nm client into .Dq master mode for connection sharing. Multiple .Fl M options places .Nm into .Dq master mode with confirmation required before slave connections are accepted. Refer to the description of .Cm ControlMaster in .Xr ssh_config 5 for details. .Pp .It Fl m Ar mac_spec A comma-separated list of MAC (message authentication code) algorithms, specified in order of preference. See the .Cm MACs keyword for more information. .Pp .It Fl N Do not execute a remote command. This is useful for just forwarding ports. .Pp .It Fl n Redirects stdin from .Pa /dev/null (actually, prevents reading from stdin). This must be used when .Nm is run in the background. A common trick is to use this to run X11 programs on a remote machine. For example, .Ic ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel. The .Nm program will be put in the background. (This does not work if .Nm needs to ask for a password or passphrase; see also the .Fl f option.) .Pp .It Fl O Ar ctl_cmd Control an active connection multiplexing master process. When the .Fl O option is specified, the .Ar ctl_cmd argument is interpreted and passed to the master process. Valid commands are: .Dq check (check that the master process is running), .Dq forward (request forwardings without command execution), .Dq cancel (cancel forwardings), .Dq exit (request the master to exit), and .Dq stop (request the master to stop accepting further multiplexing requests). .Pp .It Fl o Ar option Can be used to give options in the format used in the configuration file. This is useful for specifying options for which there is no separate command-line flag. For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact .It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs .It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher .It Ciphers .It ClearAllForwardings .It Compression .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout .It ControlMaster .It ControlPath .It ControlPersist .It DynamicForward .It EscapeChar .It ExitOnForwardFailure .It FingerprintHash .It ForwardAgent .It ForwardX11 .It ForwardX11Timeout .It ForwardX11Trusted .It GatewayPorts .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials .It HashKnownHosts .It Host .It HostbasedAuthentication .It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName .It IdentityFile .It IdentitiesOnly .It IPQoS .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It LocalCommand .It LocalForward .It LogLevel .It MACs .It Match .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication .It PermitLocalCommand .It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol .It ProxyCommand .It ProxyUseFdpass .It PubkeyAcceptedKeyTypes .It PubkeyAuthentication .It RekeyLimit .It RemoteForward .It RequestTTY .It RhostsRSAAuthentication .It RSAAuthentication .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It StreamLocalBindMask .It StreamLocalBindUnlink .It StrictHostKeyChecking .It TCPKeepAlive .It Tunnel .It TunnelDevice .It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile .It VerifyHostKeyDNS .It VisualHostKey .It XAuthLocation .El .Pp .It Fl p Ar port Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. .Pp .It Fl Q Ar query_option Queries .Nm for the algorithms supported for the specified version 2. The available features are: .Ar cipher (supported symmetric ciphers), .Ar cipher-auth (supported symmetric ciphers that support authenticated encryption), .Ar mac (supported message integrity codes), .Ar kex (key exchange algorithms), .Ar key (key types), .Ar key-cert (certificate key types), .Ar key-plain (non-certificate key types), and .Ar protocol-version (supported SSH protocol versions). .Pp .It Fl q Quiet mode. Causes most warning and diagnostic messages to be suppressed. .Pp .It Fl R Xo .Sm off .Oo Ar bind_address : Oc .Ar port : host : hostport .Sm on .Xc .It Fl R Xo .Sm off .Oo Ar bind_address : Oc .Ar port : local_socket .Sm on .Xc .It Fl R Xo .Sm off .Ar remote_socket : host : hostport .Sm on .Xc .It Fl R Xo .Sm off .Ar remote_socket : local_socket .Sm on .Xc Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the given host and port, or Unix socket, on the local side. This works by allocating a socket to listen to either a TCP .Ar port or to a Unix socket on the remote side. Whenever a connection is made to this port or Unix socket, the connection is forwarded over the secure channel, and a connection is made to either .Ar host port .Ar hostport , or .Ar local_socket , from the local machine. .Pp Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square brackets. .Pp By default, TCP listening sockets on the server will be bound to the loopback interface only. This may be overridden by specifying a .Ar bind_address . An empty .Ar bind_address , or the address .Ql * , indicates that the remote socket should listen on all interfaces. Specifying a remote .Ar bind_address will only succeed if the server's .Cm GatewayPorts option is enabled (see .Xr sshd_config 5 ) . .Pp If the .Ar port argument is .Ql 0 , the listen port will be dynamically allocated on the server and reported to the client at run time. When used together with .Ic -O forward the allocated port will be printed to the standard output. .Pp .It Fl S Ar ctl_path Specifies the location of a control socket for connection sharing, or the string .Dq none to disable connection sharing. Refer to the description of .Cm ControlPath and .Cm ControlMaster in .Xr ssh_config 5 for details. .Pp .It Fl s May be used to request invocation of a subsystem on the remote system. Subsystems facilitate the use of SSH as a secure transport for other applications (e.g.\& .Xr sftp 1 ) . The subsystem is specified as the remote command. .Pp .It Fl T Disable pseudo-terminal allocation. .Pp .It Fl t Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple .Fl t options force tty allocation, even if .Nm has no local tty. .Pp .It Fl V Display the version number and exit. .Pp .It Fl v Verbose mode. Causes .Nm to print debugging messages about its progress. This is helpful in debugging connection, authentication, and configuration problems. Multiple .Fl v options increase the verbosity. The maximum is 3. .Pp .It Fl W Ar host : Ns Ar port Requests that standard input and output on the client be forwarded to .Ar host on .Ar port over the secure channel. Implies .Fl N , .Fl T , .Cm ExitOnForwardFailure and .Cm ClearAllForwardings . .Pp .It Fl w Xo .Ar local_tun Ns Op : Ns Ar remote_tun .Xc Requests tunnel device forwarding with the specified .Xr tun 4 devices between the client .Pq Ar local_tun and the server .Pq Ar remote_tun . .Pp The devices may be specified by numerical ID or the keyword .Dq any , which uses the next available tunnel device. If .Ar remote_tun is not specified, it defaults to .Dq any . See also the .Cm Tunnel and .Cm TunnelDevice directives in .Xr ssh_config 5 . If the .Cm Tunnel directive is unset, it is set to the default tunnel mode, which is .Dq point-to-point . .Pp .It Fl X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. .Pp X11 forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the user's X authorization database) can access the local X11 display through the forwarded connection. An attacker may then be able to perform activities such as keystroke monitoring. .Pp For this reason, X11 forwarding is subjected to X11 SECURITY extension restrictions by default. Please refer to the .Nm .Fl Y option and the .Cm ForwardX11Trusted directive in .Xr ssh_config 5 for more information. .Pp .It Fl x Disables X11 forwarding. .Pp .It Fl Y Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. .Pp .It Fl y Send log information using the .Xr syslog 3 system module. By default this information is sent to stderr. .El .Pp .Nm may additionally obtain configuration data from a per-user configuration file and a system-wide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . .Sh AUTHENTICATION The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the .Cm Protocol option in .Xr ssh_config 5 or the .Fl 1 and .Fl 2 options (see above). Protocol 1 should not be used and is only offered to support legacy devices. It suffers from a number of cryptographic weaknesses and doesn't support many of the advanced features available for protocol 2. .Pp The methods available for authentication are: GSSAPI-based authentication, host-based authentication, public key authentication, challenge-response authentication, and password authentication. Authentication methods are tried in the order specified above, though .Cm PreferredAuthentications can be used to change the default order. .Pp Host-based authentication works as follows: If the machine the user logs in from is listed in .Pa /etc/hosts.equiv or .Pa /etc/shosts.equiv on the remote machine, and the user names are the same on both sides, or if the files .Pa ~/.rhosts or .Pa ~/.shosts exist in the user's home directory on the remote machine and contain a line containing the name of the client machine and the name of the user on that machine, the user is considered for login. Additionally, the server .Em must be able to verify the client's host key (see the description of .Pa /etc/ssh/ssh_known_hosts and .Pa ~/.ssh/known_hosts , below) for login to be permitted. This authentication method closes security holes due to IP spoofing, DNS spoofing, and routing spoofing. [Note to the administrator: .Pa /etc/hosts.equiv , .Pa ~/.rhosts , and the rlogin/rsh protocol in general, are inherently insecure and should be disabled if security is desired.] .Pp Public key authentication works as follows: The scheme is based on public-key cryptography, using cryptosystems where encryption and decryption are done using separate keys, and it is unfeasible to derive the decryption key from the encryption key. The idea is that each user creates a public/private key pair for authentication purposes. The server knows the public key, and only the user knows the private key. .Nm implements public key authentication protocol automatically, using one of the DSA, ECDSA, Ed25519 or RSA algorithms. The HISTORY section of .Xr ssl 8 contains a brief discussion of the DSA and RSA algorithms. .Pp The file .Pa ~/.ssh/authorized_keys lists the public keys that are permitted for logging in. When the user logs in, the .Nm program tells the server which key pair it would like to use for authentication. The client proves that it has access to the private key and the server checks that the corresponding public key is authorized to accept the account. .Pp The user creates his/her key pair by running .Xr ssh-keygen 1 . This stores the private key in .Pa ~/.ssh/identity (protocol 1), .Pa ~/.ssh/id_dsa (DSA), .Pa ~/.ssh/id_ecdsa (ECDSA), .Pa ~/.ssh/id_ed25519 (Ed25519), or .Pa ~/.ssh/id_rsa (RSA) and stores the public key in .Pa ~/.ssh/identity.pub (protocol 1), .Pa ~/.ssh/id_dsa.pub (DSA), .Pa ~/.ssh/id_ecdsa.pub (ECDSA), .Pa ~/.ssh/id_ed25519.pub (Ed25519), or .Pa ~/.ssh/id_rsa.pub (RSA) in the user's home directory. The user should then copy the public key to .Pa ~/.ssh/authorized_keys in his/her home directory on the remote machine. The .Pa authorized_keys file corresponds to the conventional .Pa ~/.rhosts file, and has one key per line, though the lines can be very long. After this, the user can log in without giving the password. .Pp A variation on public key authentication is available in the form of certificate authentication: instead of a set of public/private keys, signed certificates are used. This has the advantage that a single trusted certification authority can be used in place of many public/private keys. See the CERTIFICATES section of .Xr ssh-keygen 1 for more information. .Pp The most convenient way to use public key or certificate authentication may be with an authentication agent. See .Xr ssh-agent 1 and (optionally) the .Cm AddKeysToAgent directive in .Xr ssh_config 5 for more information. .Pp Challenge-response authentication works as follows: The server sends an arbitrary .Qq challenge text, and prompts for a response. Examples of challenge-response authentication include .Bx Authentication (see .Xr login.conf 5 ) and PAM (some .Pf non- Ox systems). .Pp Finally, if other authentication methods fail, .Nm prompts the user for a password. The password is sent to the remote host for checking; however, since all communications are encrypted, the password cannot be seen by someone listening on the network. .Pp .Nm automatically maintains and checks a database containing identification for all hosts it has ever been used with. Host keys are stored in .Pa ~/.ssh/known_hosts in the user's home directory. Additionally, the file .Pa /etc/ssh/ssh_known_hosts is automatically checked for known hosts. Any new hosts are automatically added to the user's file. If a host's identification ever changes, .Nm warns about this and disables password authentication to prevent server spoofing or man-in-the-middle attacks, which could otherwise be used to circumvent the encryption. The .Cm StrictHostKeyChecking option can be used to control logins to machines whose host key is not known or has changed. .Pp When the user's identity has been accepted by the server, the server either executes the given command in a non-interactive session or, if no command has been specified, logs into the machine and gives the user a normal shell as an interactive session. All communication with the remote command or shell will be automatically encrypted. .Pp If an interactive session is requested .Nm by default will only request a pseudo-terminal (pty) for interactive sessions when the client has one. The flags .Fl T and .Fl t can be used to override this behaviour. .Pp If a pseudo-terminal has been allocated the user may use the escape characters noted below. .Pp If no pseudo-terminal has been allocated, the session is transparent and can be used to reliably transfer binary data. On most systems, setting the escape character to .Dq none will also make the session transparent even if a tty is used. .Pp The session terminates when the command or shell on the remote machine exits and all X11 and TCP connections have been closed. .Sh ESCAPE CHARACTERS When a pseudo-terminal has been requested, .Nm supports a number of functions through the use of an escape character. .Pp A single tilde character can be sent as .Ic ~~ or by following the tilde by a character other than those described below. The escape character must always follow a newline to be interpreted as special. The escape character can be changed in configuration files using the .Cm EscapeChar configuration directive or on the command line by the .Fl e option. .Pp The supported escapes (assuming the default .Ql ~ ) are: .Bl -tag -width Ds .It Cm ~. Disconnect. .It Cm ~^Z Background .Nm . .It Cm ~# List forwarded connections. .It Cm ~& Background .Nm at logout when waiting for forwarded connection / X11 sessions to terminate. .It Cm ~? Display a list of escape characters. .It Cm ~B Send a BREAK to the remote system (only useful if the peer supports it). .It Cm ~C Open command line. Currently this allows the addition of port forwardings using the .Fl L , .Fl R and .Fl D options (see above). It also allows the cancellation of existing port-forwardings with .Sm off .Fl KL Oo Ar bind_address : Oc Ar port .Sm on for local, .Sm off .Fl KR Oo Ar bind_address : Oc Ar port .Sm on for remote and .Sm off .Fl KD Oo Ar bind_address : Oc Ar port .Sm on for dynamic port-forwardings. .Ic !\& Ns Ar command allows the user to execute a local command if the .Ic PermitLocalCommand option is enabled in .Xr ssh_config 5 . Basic help is available, using the .Fl h option. .It Cm ~R Request rekeying of the connection (only useful if the peer supports it). .It Cm ~V Decrease the verbosity .Pq Ic LogLevel when errors are being written to stderr. .It Cm ~v Increase the verbosity .Pq Ic LogLevel when errors are being written to stderr. .El .Sh TCP FORWARDING Forwarding of arbitrary TCP connections over the secure channel can be specified either on the command line or in a configuration file. One possible application of TCP forwarding is a secure connection to a mail server; another is going through firewalls. .Pp In the example below, we look at encrypting communication between an IRC client and server, even though the IRC server does not directly support encrypted communications. This works as follows: the user connects to the remote host using .Nm , specifying a port to be used to forward connections to the remote server. After that it is possible to start the service which is to be encrypted on the client machine, connecting to the same local port, and .Nm will encrypt and forward the connection. .Pp The following example tunnels an IRC session from client machine .Dq 127.0.0.1 (localhost) to remote server .Dq server.example.com : .Bd -literal -offset 4n $ ssh -f -L 1234:localhost:6667 server.example.com sleep 10 $ irc -c '#users' -p 1234 pinky 127.0.0.1 .Ed .Pp This tunnels a connection to IRC server .Dq server.example.com , joining channel .Dq #users , nickname .Dq pinky , using port 1234. It doesn't matter which port is used, as long as it's greater than 1023 (remember, only root can open sockets on privileged ports) and doesn't conflict with any ports already in use. The connection is forwarded to port 6667 on the remote server, since that's the standard port for IRC services. .Pp The .Fl f option backgrounds .Nm and the remote command .Dq sleep 10 is specified to allow an amount of time (10 seconds, in the example) to start the service which is to be tunnelled. If no connections are made within the time specified, .Nm will exit. .Sh X11 FORWARDING If the .Cm ForwardX11 variable is set to .Dq yes (or see the description of the .Fl X , .Fl x , and .Fl Y options above) and the user is using X11 (the .Ev DISPLAY environment variable is set), the connection to the X11 display is automatically forwarded to the remote side in such a way that any X11 programs started from the shell (or command) will go through the encrypted channel, and the connection to the real X server will be made from the local machine. The user should not manually set .Ev DISPLAY . Forwarding of X11 connections can be configured on the command line or in configuration files. .Pp The .Ev DISPLAY value set by .Nm will point to the server machine, but with a display number greater than zero. This is normal, and happens because .Nm creates a .Dq proxy X server on the server machine for forwarding the connections over the encrypted channel. .Pp .Nm will also automatically set up Xauthority data on the server machine. For this purpose, it will generate a random authorization cookie, store it in Xauthority on the server, and verify that any forwarded connections carry this cookie and replace it by the real cookie when the connection is opened. The real authentication cookie is never sent to the server machine (and no cookies are sent in the plain). .Pp If the .Cm ForwardAgent variable is set to .Dq yes (or see the description of the .Fl A and .Fl a options above) and the user is using an authentication agent, the connection to the agent is automatically forwarded to the remote side. .Sh VERIFYING HOST KEYS When connecting to a server for the first time, a fingerprint of the server's public key is presented to the user (unless the option .Cm StrictHostKeyChecking has been disabled). Fingerprints can be determined using .Xr ssh-keygen 1 : .Pp .Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key .Pp If the fingerprint is already known, it can be matched and the key can be accepted or rejected. If only legacy (MD5) fingerprints for the server are available, the .Xr ssh-keygen 1 .Fl E option may be used to downgrade the fingerprint algorithm to match. .Pp Because of the difficulty of comparing host keys just by looking at fingerprint strings, there is also support to compare host keys visually, using .Em random art . By setting the .Cm VisualHostKey option to .Dq yes , a small ASCII graphic gets displayed on every login to a server, no matter if the session itself is interactive or not. By learning the pattern a known server produces, a user can easily find out that the host key has changed when a completely different pattern is displayed. Because these patterns are not unambiguous however, a pattern that looks similar to the pattern remembered only gives a good probability that the host key is the same, not guaranteed proof. .Pp To get a listing of the fingerprints along with their random art for all known hosts, the following command line can be used: .Pp .Dl $ ssh-keygen -lv -f ~/.ssh/known_hosts .Pp If the fingerprint is unknown, an alternative method of verification is available: SSH fingerprints verified by DNS. An additional resource record (RR), SSHFP, is added to a zonefile and the connecting client is able to match the fingerprint with that of the key presented. .Pp In this example, we are connecting a client to a server, .Dq host.example.com . The SSHFP resource records should first be added to the zonefile for host.example.com: .Bd -literal -offset indent $ ssh-keygen -r host.example.com. .Ed .Pp The output lines will have to be added to the zonefile. To check that the zone is answering fingerprint queries: .Pp .Dl $ dig -t SSHFP host.example.com .Pp Finally the client connects: .Bd -literal -offset indent $ ssh -o "VerifyHostKeyDNS ask" host.example.com [...] Matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)? .Ed .Pp See the .Cm VerifyHostKeyDNS option in .Xr ssh_config 5 for more information. .Sh SSH-BASED VIRTUAL PRIVATE NETWORKS .Nm contains support for Virtual Private Network (VPN) tunnelling using the .Xr tun 4 network pseudo-device, allowing two networks to be joined securely. The .Xr sshd_config 5 configuration option .Cm PermitTunnel controls whether the server supports this, and at what level (layer 2 or 3 traffic). .Pp The following example would connect client network 10.0.50.0/24 with remote network 10.0.99.0/24 using a point-to-point connection from 10.1.1.1 to 10.1.1.2, provided that the SSH server running on the gateway to the remote network, at 192.168.1.15, allows it. .Pp On the client: .Bd -literal -offset indent # ssh -f -w 0:1 192.168.1.15 true # ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252 # route add 10.0.99.0/24 10.1.1.2 .Ed .Pp On the server: .Bd -literal -offset indent # ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252 # route add 10.0.50.0/24 10.1.1.1 .Ed .Pp Client access may be more finely tuned via the .Pa /root/.ssh/authorized_keys file (see below) and the .Cm PermitRootLogin server option. The following entry would permit connections on .Xr tun 4 device 1 from user .Dq jane and on tun device 2 from user .Dq john , if .Cm PermitRootLogin is set to .Dq forced-commands-only : .Bd -literal -offset 2n tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john .Ed .Pp Since an SSH-based setup entails a fair amount of overhead, it may be more suited to temporary setups, such as for wireless VPNs. More permanent VPNs are better provided by tools such as .Xr ipsecctl 8 and .Xr isakmpd 8 . .Sh ENVIRONMENT .Nm will normally set the following environment variables: .Bl -tag -width "SSH_ORIGINAL_COMMAND" .It Ev DISPLAY The .Ev DISPLAY variable indicates the location of the X11 server. It is automatically set by .Nm to point to a value of the form .Dq hostname:n , where .Dq hostname indicates the host where the shell runs, and .Sq n is an integer \*(Ge 1. .Nm uses this special value to forward X11 connections over the secure channel. The user should normally not set .Ev DISPLAY explicitly, as that will render the X11 connection insecure (and will require the user to manually copy any required authorization cookies). .It Ev HOME Set to the path of the user's home directory. .It Ev LOGNAME Synonym for .Ev USER ; set for compatibility with systems that use this variable. .It Ev MAIL Set to the path of the user's mailbox. .It Ev PATH Set to the default .Ev PATH , as specified when compiling .Nm . .It Ev SSH_ASKPASS If .Nm needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If .Nm does not have a terminal associated with it but .Ev DISPLAY and .Ev SSH_ASKPASS are set, it will execute the program specified by .Ev SSH_ASKPASS and open an X11 window to read the passphrase. This is particularly useful when calling .Nm from a .Pa .xsession or related script. (Note that on some machines it may be necessary to redirect the input from .Pa /dev/null to make this work.) .It Ev SSH_AUTH_SOCK Identifies the path of a .Ux Ns -domain socket used to communicate with the agent. .It Ev SSH_CONNECTION Identifies the client and server ends of the connection. The variable contains four space-separated values: client IP address, client port number, server IP address, and server port number. .It Ev SSH_ORIGINAL_COMMAND This variable contains the original command line if a forced command is executed. It can be used to extract the original arguments. .It Ev SSH_TTY This is set to the name of the tty (path to the device) associated with the current shell or command. If the current session has no tty, this variable is not set. .It Ev TZ This variable is set to indicate the present time zone if it was set when the daemon was started (i.e. the daemon passes the value on to new connections). .It Ev USER Set to the name of the user logging in. .El .Pp Additionally, .Nm reads .Pa ~/.ssh/environment , and adds lines of the format .Dq VARNAME=value to the environment if the file exists and users are allowed to change their environment. For more information, see the .Cm PermitUserEnvironment option in .Xr sshd_config 5 . .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.rhosts This file is used for host-based authentication (see above). On some machines this file may need to be world-readable if the user's home directory is on an NFS partition, because .Xr sshd 8 reads it as root. Additionally, this file must be owned by the user, and must not have write permissions for anyone else. The recommended permission for most machines is read/write for the user, and not accessible by others. .Pp .It Pa ~/.shosts This file is used in exactly the same way as .Pa .rhosts , but allows host-based authentication without permitting login with rlogin/rsh. .Pp .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described in the .Xr sshd 8 manual page. This file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. .Pp .It Pa ~/.ssh/config This is the per-user configuration file. The file format and configuration options are described in .Xr ssh_config 5 . Because of the potential for abuse, this file must have strict permissions: read/write for the user, and not writable by others. .Pp .It Pa ~/.ssh/environment Contains additional definitions for environment variables; see .Sx ENVIRONMENT , above. .Pp .It Pa ~/.ssh/identity .It Pa ~/.ssh/id_dsa .It Pa ~/.ssh/id_ecdsa .It Pa ~/.ssh/id_ed25519 .It Pa ~/.ssh/id_rsa Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not accessible by others (read/write/execute). .Nm will simply ignore a private key file if it is accessible by others. It is possible to specify a passphrase when generating the key which will be used to encrypt the sensitive part of this file using 3DES. .Pp .It Pa ~/.ssh/identity.pub .It Pa ~/.ssh/id_dsa.pub .It Pa ~/.ssh/id_ecdsa.pub .It Pa ~/.ssh/id_ed25519.pub .It Pa ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. .Pp .It Pa ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. See .Xr sshd 8 for further details of the format of this file. .Pp .It Pa ~/.ssh/rc Commands in this file are executed by .Nm when the user logs in, just before the user's shell (or command) is started. See the .Xr sshd 8 manual page for more information. .Pp .It Pa /etc/hosts.equiv This file is for host-based authentication (see above). It should only be writable by root. .Pp .It Pa /etc/shosts.equiv This file is used in exactly the same way as .Pa hosts.equiv , but allows host-based authentication without permitting login with rlogin/rsh. .Pp .It Pa /etc/ssh/ssh_config Systemwide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . .Pp .It Pa /etc/ssh/ssh_host_key .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key .It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are used for host-based authentication. .Pp .It Pa /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the organization. It should be world-readable. See .Xr sshd 8 for further details of the format of this file. .Pp .It Pa /etc/ssh/sshrc Commands in this file are executed by .Nm when the user logs in, just before the user's shell (or command) is started. See the .Xr sshd 8 manual page for more information. .El .Sh EXIT STATUS .Nm exits with the exit status of the remote command or with 255 if an error occurred. .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , .Xr ssh-keyscan 1 , .Xr tun 4 , .Xr ssh_config 5 , .Xr ssh-keysign 8 , .Xr sshd 8 .Sh STANDARDS .Rs .%A S. Lehtinen .%A C. Lonvick .%D January 2006 .%R RFC 4250 .%T The Secure Shell (SSH) Protocol Assigned Numbers .Re .Pp .Rs .%A T. Ylonen .%A C. Lonvick .%D January 2006 .%R RFC 4251 .%T The Secure Shell (SSH) Protocol Architecture .Re .Pp .Rs .%A T. Ylonen .%A C. Lonvick .%D January 2006 .%R RFC 4252 .%T The Secure Shell (SSH) Authentication Protocol .Re .Pp .Rs .%A T. Ylonen .%A C. Lonvick .%D January 2006 .%R RFC 4253 .%T The Secure Shell (SSH) Transport Layer Protocol .Re .Pp .Rs .%A T. Ylonen .%A C. Lonvick .%D January 2006 .%R RFC 4254 .%T The Secure Shell (SSH) Connection Protocol .Re .Pp .Rs .%A J. Schlyter .%A W. Griffin .%D January 2006 .%R RFC 4255 .%T Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints .Re .Pp .Rs .%A F. Cusack .%A M. Forssen .%D January 2006 .%R RFC 4256 .%T Generic Message Exchange Authentication for the Secure Shell Protocol (SSH) .Re .Pp .Rs .%A J. Galbraith .%A P. Remaker .%D January 2006 .%R RFC 4335 .%T The Secure Shell (SSH) Session Channel Break Extension .Re .Pp .Rs .%A M. Bellare .%A T. Kohno .%A C. Namprempre .%D January 2006 .%R RFC 4344 .%T The Secure Shell (SSH) Transport Layer Encryption Modes .Re .Pp .Rs .%A B. Harris .%D January 2006 .%R RFC 4345 .%T Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol .Re .Pp .Rs .%A M. Friedl .%A N. Provos .%A W. Simpson .%D March 2006 .%R RFC 4419 .%T Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol .Re .Pp .Rs .%A J. Galbraith .%A R. Thayer .%D November 2006 .%R RFC 4716 .%T The Secure Shell (SSH) Public Key File Format .Re .Pp .Rs .%A D. Stebila .%A J. Green .%D December 2009 .%R RFC 5656 .%T Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer .Re .Pp .Rs .%A A. Perrig .%A D. Song .%D 1999 .%O International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99) .%T Hash Visualization: a New Technique to improve Real-World Security .Re .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.2p2/ssh.c010064400017500001750000001701571267006270000124260ustar00djmdjm/* $OpenBSD: ssh.c,v 1.436 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Ssh client program. This program can be used to log into a remote machine. * The software supports strong authentication, encryption, and forwarding * of X11, TCP/IP, and authentication connections. * * 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) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved. * * Modified to work with SSL by Niels Provos * in Canada (German citizen). * * 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 #ifdef HAVE_SYS_STAT_H # include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef WITH_OPENSSL #include #include #endif #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" #include "canohost.h" #include "compat.h" #include "cipher.h" #include "digest.h" #include "packet.h" #include "buffer.h" #include "channels.h" #include "key.h" #include "authfd.h" #include "authfile.h" #include "pathnames.h" #include "dispatch.h" #include "clientloop.h" #include "log.h" #include "misc.h" #include "readconf.h" #include "sshconnect.h" #include "kex.h" #include "mac.h" #include "sshpty.h" #include "match.h" #include "msg.h" #include "uidswap.h" #include "version.h" #include "ssherr.h" #include "myproposal.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif extern char *__progname; /* Saves a copy of argv for setproctitle emulation */ #ifndef HAVE_SETPROCTITLE static char **saved_av; #endif /* Flag indicating whether debug mode is on. May be set on the command line. */ int debug_flag = 0; /* Flag indicating whether a tty should be requested */ int tty_flag = 0; /* don't exec a shell */ int no_shell_flag = 0; /* * Flag indicating that nothing should be read from stdin. This can be set * on the command line. */ int stdin_null_flag = 0; /* * Flag indicating that the current process should be backgrounded and * a new slave launched in the foreground for ControlPersist. */ int need_controlpersist_detach = 0; /* Copies of flags for ControlPersist foreground slave */ int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty; /* * Flag indicating that ssh should fork after authentication. This is useful * so that the passphrase can be entered manually, and then ssh goes to the * background. */ int fork_after_authentication_flag = 0; /* forward stdio to remote host and port */ char *stdio_forward_host = NULL; int stdio_forward_port = 0; /* * General data structure for command line options and options configurable * in configuration files. See readconf.h. */ Options options; /* optional user configfile */ char *config = NULL; /* * Name of the host we are connecting to. This is the name given on the * command line, or the HostName specified for the user-supplied name in a * configuration file. */ char *host; /* socket address the host resolves to */ struct sockaddr_storage hostaddr; /* Private host keys. */ Sensitive sensitive_data; /* Original real UID. */ uid_t original_real_uid; uid_t original_effective_uid; /* command to be executed */ Buffer command; /* Should we execute a command or invoke a subsystem? */ int subsystem_flag = 0; /* # of replies received for global requests */ static int remote_forward_confirms_received = 0; /* mux.c */ extern int muxserver_sock; extern u_int muxclient_command; /* Prints a help message to the user. This function never returns. */ static void usage(void) { fprintf(stderr, "usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" " [-F configfile] [-I pkcs11] [-i identity_file] [-L address]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-Q query_option] [-R address] [-S ctl_path] [-W host:port]\n" " [-w local_tun[:remote_tun]] [user@]hostname [command]\n" ); exit(255); } static int ssh_session(void); static int ssh_session2(void); static void load_public_identity_files(void); static void main_sigchld_handler(int); /* from muxclient.c */ void muxclient(const char *); void muxserver_listen(void); /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ static void tilde_expand_paths(char **paths, u_int num_paths) { u_int i; char *cp; for (i = 0; i < num_paths; i++) { cp = tilde_expand_filename(paths[i], original_real_uid); free(paths[i]); paths[i] = cp; } } /* * Attempt to resolve a host name / port to a set of addresses and * optionally return any CNAMEs encountered along the way. * Returns NULL on failure. * NB. this function must operate with a options having undefined members. */ static struct addrinfo * resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) { char strport[NI_MAXSERV]; struct addrinfo hints, *res; int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; if (port <= 0) port = default_ssh_port(); snprintf(strport, sizeof strport, "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = options.address_family == -1 ? AF_UNSPEC : options.address_family; hints.ai_socktype = SOCK_STREAM; if (cname != NULL) hints.ai_flags = AI_CANONNAME; if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { if (logerr || (gaierr != EAI_NONAME && gaierr != EAI_NODATA)) loglevel = SYSLOG_LEVEL_ERROR; do_log2(loglevel, "%s: Could not resolve hostname %.100s: %s", __progname, name, ssh_gai_strerror(gaierr)); return NULL; } if (cname != NULL && res->ai_canonname != NULL) { if (strlcpy(cname, res->ai_canonname, clen) >= clen) { error("%s: host \"%s\" cname \"%s\" too long (max %lu)", __func__, name, res->ai_canonname, (u_long)clen); if (clen > 0) *cname = '\0'; } } return res; } /* * Attempt to resolve a numeric host address / port to a single address. * Returns a canonical address string. * Returns NULL on failure. * NB. this function must operate with a options having undefined members. */ static struct addrinfo * resolve_addr(const char *name, int port, char *caddr, size_t clen) { char addr[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo hints, *res; int gaierr; if (port <= 0) port = default_ssh_port(); snprintf(strport, sizeof strport, "%u", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = options.address_family == -1 ? AF_UNSPEC : options.address_family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { debug2("%s: could not resolve name %.100s as address: %s", __func__, name, ssh_gai_strerror(gaierr)); return NULL; } if (res == NULL) { debug("%s: getaddrinfo %.100s returned no addresses", __func__, name); return NULL; } if (res->ai_next != NULL) { debug("%s: getaddrinfo %.100s returned multiple addresses", __func__, name); goto fail; } if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen, addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) { debug("%s: Could not format address for name %.100s: %s", __func__, name, ssh_gai_strerror(gaierr)); goto fail; } if (strlcpy(caddr, addr, clen) >= clen) { error("%s: host \"%s\" addr \"%s\" too long (max %lu)", __func__, name, addr, (u_long)clen); if (clen > 0) *caddr = '\0'; fail: freeaddrinfo(res); return NULL; } return res; } /* * Check whether the cname is a permitted replacement for the hostname * and perform the replacement if it is. * NB. this function must operate with a options having undefined members. */ static int check_follow_cname(char **namep, const char *cname) { int i; struct allowed_cname *rule; if (*cname == '\0' || options.num_permitted_cnames == 0 || strcmp(*namep, cname) == 0) return 0; if (options.canonicalize_hostname == SSH_CANONICALISE_NO) return 0; /* * Don't attempt to canonicalize names that will be interpreted by * a proxy unless the user specifically requests so. */ if (!option_clear_or_none(options.proxy_command) && options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) return 0; debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); for (i = 0; i < options.num_permitted_cnames; i++) { rule = options.permitted_cnames + i; if (match_pattern_list(*namep, rule->source_list, 1) != 1 || match_pattern_list(cname, rule->target_list, 1) != 1) continue; verbose("Canonicalized DNS aliased hostname " "\"%s\" => \"%s\"", *namep, cname); free(*namep); *namep = xstrdup(cname); return 1; } return 0; } /* * Attempt to resolve the supplied hostname after applying the user's * canonicalization rules. Returns the address list for the host or NULL * if no name was found after canonicalization. * NB. this function must operate with a options having undefined members. */ static struct addrinfo * resolve_canonicalize(char **hostp, int port) { int i, ndots; char *cp, *fullhost, newname[NI_MAXHOST]; struct addrinfo *addrs; if (options.canonicalize_hostname == SSH_CANONICALISE_NO) return NULL; /* * Don't attempt to canonicalize names that will be interpreted by * a proxy unless the user specifically requests so. */ if (!option_clear_or_none(options.proxy_command) && options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) return NULL; /* Try numeric hostnames first */ if ((addrs = resolve_addr(*hostp, port, newname, sizeof(newname))) != NULL) { debug2("%s: hostname %.100s is address", __func__, *hostp); if (strcasecmp(*hostp, newname) != 0) { debug2("%s: canonicalised address \"%s\" => \"%s\"", __func__, *hostp, newname); free(*hostp); *hostp = xstrdup(newname); } return addrs; } /* If domain name is anchored, then resolve it now */ if ((*hostp)[strlen(*hostp) - 1] == '.') { debug3("%s: name is fully qualified", __func__); fullhost = xstrdup(*hostp); if ((addrs = resolve_host(fullhost, port, 0, newname, sizeof(newname))) != NULL) goto found; free(fullhost); goto notfound; } /* Don't apply canonicalization to sufficiently-qualified hostnames */ ndots = 0; for (cp = *hostp; *cp != '\0'; cp++) { if (*cp == '.') ndots++; } if (ndots > options.canonicalize_max_dots) { debug3("%s: not canonicalizing hostname \"%s\" (max dots %d)", __func__, *hostp, options.canonicalize_max_dots); return NULL; } /* Attempt each supplied suffix */ for (i = 0; i < options.num_canonical_domains; i++) { *newname = '\0'; xasprintf(&fullhost, "%s.%s.", *hostp, options.canonical_domains[i]); debug3("%s: attempting \"%s\" => \"%s\"", __func__, *hostp, fullhost); if ((addrs = resolve_host(fullhost, port, 0, newname, sizeof(newname))) == NULL) { free(fullhost); continue; } found: /* Remove trailing '.' */ fullhost[strlen(fullhost) - 1] = '\0'; /* Follow CNAME if requested */ if (!check_follow_cname(&fullhost, newname)) { debug("Canonicalized hostname \"%s\" => \"%s\"", *hostp, fullhost); } free(*hostp); *hostp = fullhost; return addrs; } notfound: if (!options.canonicalize_fallback_local) fatal("%s: Could not resolve host \"%s\"", __progname, *hostp); debug2("%s: host %s not found in any suffix", __func__, *hostp); return NULL; } /* * Read per-user configuration file. Ignore the system wide config * file if the user specifies a config file on the command line. */ static void process_config_files(const char *host_arg, struct passwd *pw, int post_canon) { char buf[PATH_MAX]; int r; if (config != NULL) { if (strcasecmp(config, "none") != 0 && !read_config_file(config, pw, host, host_arg, &options, SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) (void)read_config_file(buf, pw, host, host_arg, &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)); /* Read systemwide configuration file after user config. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, host_arg, &options, post_canon ? SSHCONF_POSTCANON : 0); } } /* Rewrite the port number in an addrinfo list of addresses */ static void set_addrinfo_port(struct addrinfo *addrs, int port) { struct addrinfo *addr; for (addr = addrs; addr != NULL; addr = addr->ai_next) { switch (addr->ai_family) { case AF_INET: ((struct sockaddr_in *)addr->ai_addr)-> sin_port = htons(port); break; case AF_INET6: ((struct sockaddr_in6 *)addr->ai_addr)-> sin6_port = htons(port); break; } } } /* * Main program for the ssh client. */ int main(int ac, char **av) { int i, r, opt, exit_status, use_syslog, config_test = 0; char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; struct stat st; struct passwd *pw; int timeout_ms; extern int optind, optreset; extern char *optarg; struct Forward fwd; struct addrinfo *addrs = NULL; struct ssh_digest_ctx *md; u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); __progname = ssh_get_progname(av[0]); #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ /* Save argv so it isn't clobbered by setproctitle() emulation */ saved_av = xcalloc(ac + 1, sizeof(*saved_av)); for (i = 0; i < ac; i++) saved_av[i] = xstrdup(av[i]); saved_av[i] = NULL; compat_init_setproctitle(ac, av); av = saved_av; #endif /* * Discard other fds that are hanging around. These can cause problem * with backgrounded ssh processes started by ControlPersist. */ closefrom(STDERR_FILENO + 1); /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). */ original_real_uid = getuid(); original_effective_uid = geteuid(); /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are * ready to create the privileged port, and will permanently drop * them when the port has been created (actually, when the connection * has been made, as we may need to create the port several times). */ PRIV_END; #ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } #endif /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { logit("No user exists for uid %lu", (u_long)original_real_uid); exit(255); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); /* * Set our umask to something reasonable, as some files are created * with the default umask. This will make them world-readable but * writable only by the owner, which is ok for all files for which we * don't set the modes explicitly. */ umask(022); /* * Initialize option structure to indicate that no values have been * set. */ initialize_options(&options); /* Parse command-line arguments. */ host = NULL; use_syslog = 0; logfile = NULL; argv0 = av[0]; again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; break; case '2': options.protocol = SSH_PROTO_2; break; case '4': options.address_family = AF_INET; break; case '6': options.address_family = AF_INET6; break; case 'n': stdin_null_flag = 1; break; case 'f': fork_after_authentication_flag = 1; stdin_null_flag = 1; break; case 'x': options.forward_x11 = 0; break; case 'X': options.forward_x11 = 1; break; case 'y': use_syslog = 1; break; case 'E': logfile = optarg; break; case 'G': config_test = 1; break; case 'Y': options.forward_x11 = 1; options.forward_x11_trusted = 1; break; case 'g': options.fwd_opts.gateway_ports = 1; break; case 'O': if (stdio_forward_host != NULL) fatal("Cannot specify multiplexing " "command with -W"); else if (muxclient_command != 0) fatal("Multiplexing command already specified"); if (strcmp(optarg, "check") == 0) muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; else if (strcmp(optarg, "forward") == 0) muxclient_command = SSHMUX_COMMAND_FORWARD; else if (strcmp(optarg, "exit") == 0) muxclient_command = SSHMUX_COMMAND_TERMINATE; else if (strcmp(optarg, "stop") == 0) muxclient_command = SSHMUX_COMMAND_STOP; else if (strcmp(optarg, "cancel") == 0) muxclient_command = SSHMUX_COMMAND_CANCEL_FWD; else fatal("Invalid multiplex command."); break; case 'P': /* deprecated */ options.use_privileged_port = 0; break; case 'Q': cp = NULL; if (strcmp(optarg, "cipher") == 0) cp = cipher_alg_list('\n', 0); else if (strcmp(optarg, "cipher-auth") == 0) cp = cipher_alg_list('\n', 1); else if (strcmp(optarg, "mac") == 0) cp = mac_alg_list('\n'); else if (strcmp(optarg, "kex") == 0) cp = kex_alg_list('\n'); else if (strcmp(optarg, "key") == 0) cp = key_alg_list(0, 0); else if (strcmp(optarg, "key-cert") == 0) cp = key_alg_list(1, 0); else if (strcmp(optarg, "key-plain") == 0) cp = key_alg_list(0, 1); else if (strcmp(optarg, "protocol-version") == 0) { #ifdef WITH_SSH1 cp = xstrdup("1\n2"); #else cp = xstrdup("2"); #endif } if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); printf("%s\n", cp); free(cp); exit(0); break; case 'a': options.forward_agent = 0; break; case 'A': options.forward_agent = 1; break; case 'k': options.gss_deleg_creds = 0; break; case 'K': options.gss_authentication = 1; options.gss_deleg_creds = 1; break; case 'i': p = tilde_expand_filename(optarg, original_real_uid); if (stat(p, &st) < 0) fprintf(stderr, "Warning: Identity file %s " "not accessible: %s.\n", p, strerror(errno)); else add_identity_file(&options, NULL, p, 1); free(p); break; case 'I': #ifdef ENABLE_PKCS11 free(options.pkcs11_provider); options.pkcs11_provider = xstrdup(optarg); #else fprintf(stderr, "no support for PKCS#11.\n"); #endif break; case 't': if (options.request_tty == REQUEST_TTY_YES) options.request_tty = REQUEST_TTY_FORCE; else options.request_tty = REQUEST_TTY_YES; break; case 'v': if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; } else { if (options.log_level < SYSLOG_LEVEL_DEBUG3) options.log_level++; } break; case 'V': fprintf(stderr, "%s, %s\n", SSH_RELEASE, #ifdef WITH_OPENSSL SSLeay_version(SSLEAY_VERSION) #else "without OpenSSL" #endif ); if (opt == 'V') exit(0); break; case 'w': if (options.tun_open == -1) options.tun_open = SSH_TUNMODE_DEFAULT; options.tun_local = a2tun(optarg, &options.tun_remote); if (options.tun_local == SSH_TUNID_ERR) { fprintf(stderr, "Bad tun device '%s'\n", optarg); exit(255); } break; case 'W': if (stdio_forward_host != NULL) fatal("stdio forward already specified"); if (muxclient_command != 0) fatal("Cannot specify stdio forward with -O"); if (parse_forward(&fwd, optarg, 1, 0)) { stdio_forward_host = fwd.listen_host; stdio_forward_port = fwd.listen_port; free(fwd.connect_host); } else { fprintf(stderr, "Bad stdio forwarding specification '%s'\n", optarg); exit(255); } options.request_tty = REQUEST_TTY_NO; no_shell_flag = 1; options.clear_forwardings = 1; options.exit_on_forward_failure = 1; break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': if (optarg[0] == '^' && optarg[2] == 0 && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; else if (strlen(optarg) == 1) options.escape_char = (u_char) optarg[0]; else if (strcmp(optarg, "none") == 0) options.escape_char = SSH_ESCAPECHAR_NONE; else { fprintf(stderr, "Bad escape character '%s'.\n", optarg); exit(255); } break; case 'c': if (ciphers_valid(*optarg == '+' ? optarg + 1 : optarg)) { /* SSH2 only */ free(options.ciphers); options.ciphers = xstrdup(optarg); options.cipher = SSH_CIPHER_INVALID; break; } /* SSH1 only */ options.cipher = cipher_number(optarg); if (options.cipher == -1) { fprintf(stderr, "Unknown cipher type '%s'\n", optarg); exit(255); } if (options.cipher == SSH_CIPHER_3DES) options.ciphers = xstrdup("3des-cbc"); else if (options.cipher == SSH_CIPHER_BLOWFISH) options.ciphers = xstrdup("blowfish-cbc"); else options.ciphers = xstrdup(KEX_CLIENT_ENCRYPT); break; case 'm': if (mac_valid(optarg)) { free(options.macs); options.macs = xstrdup(optarg); } else { fprintf(stderr, "Unknown mac type '%s'\n", optarg); exit(255); } break; case 'M': if (options.control_master == SSHCTL_MASTER_YES) options.control_master = SSHCTL_MASTER_ASK; else options.control_master = SSHCTL_MASTER_YES; break; case 'p': options.port = a2port(optarg); if (options.port <= 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(255); } break; case 'l': options.user = optarg; break; case 'L': if (parse_forward(&fwd, optarg, 0, 0)) add_local_forward(&options, &fwd); else { fprintf(stderr, "Bad local forwarding specification '%s'\n", optarg); exit(255); } break; case 'R': if (parse_forward(&fwd, optarg, 0, 1)) { add_remote_forward(&options, &fwd); } else { fprintf(stderr, "Bad remote forwarding specification " "'%s'\n", optarg); exit(255); } break; case 'D': if (parse_forward(&fwd, optarg, 1, 0)) { add_local_forward(&options, &fwd); } else { fprintf(stderr, "Bad dynamic forwarding specification " "'%s'\n", optarg); exit(255); } break; case 'C': options.compression = 1; break; case 'N': no_shell_flag = 1; options.request_tty = REQUEST_TTY_NO; break; case 'T': options.request_tty = REQUEST_TTY_NO; break; case 'o': line = xstrdup(optarg); if (process_config_line(&options, pw, host ? host : "", host ? host : "", line, "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); break; case 's': subsystem_flag = 1; break; case 'S': free(options.control_path); options.control_path = xstrdup(optarg); break; case 'b': options.bind_address = optarg; break; case 'F': config = optarg; break; default: usage(); } } ac -= optind; av += optind; if (ac > 0 && !host) { if (strrchr(*av, '@')) { p = xstrdup(*av); cp = strrchr(p, '@'); if (cp == NULL || cp == p) usage(); options.user = p; *cp = '\0'; host = xstrdup(++cp); } else host = xstrdup(*av); if (ac > 1) { optind = optreset = 1; goto again; } ac--, av++; } /* Check that we got a host name. */ if (!host) usage(); host_arg = xstrdup(host); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); #endif /* Initialize the command to execute on remote host. */ buffer_init(&command); /* * Save the command to execute on the remote host in a buffer. There * is no limit on the length of the command, except by the maximum * packet size. Also sets the tty flag if there is no command. */ if (!ac) { /* No command specified - execute shell on a tty. */ if (subsystem_flag) { fprintf(stderr, "You must specify a subsystem to invoke.\n"); usage(); } } else { /* A command has been specified. Store it into the buffer. */ for (i = 0; i < ac; i++) { if (i) buffer_append(&command, " ", 1); buffer_append(&command, av[i], strlen(av[i])); } } /* Cannot fork to background if no command. */ if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) fatal("Cannot fork into background without a command " "to execute."); /* * Initialize "log" output. Since we are the client all output * goes to stderr unless otherwise specified by -y or -E. */ if (use_syslog && logfile != NULL) fatal("Can't specify both -y and -E"); if (logfile != NULL) log_redirect_stderr_to(logfile); log_init(argv0, options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, !use_syslog); if (debug_flag) logit("%s, %s", SSH_RELEASE, #ifdef WITH_OPENSSL SSLeay_version(SSLEAY_VERSION) #else "without OpenSSL" #endif ); /* Parse the configuration files */ process_config_files(host_arg, pw, 0); /* Hostname canonicalisation needs a few options filled. */ fill_default_options_for_canonicalization(&options); /* If the user has replaced the hostname then take it into use now */ if (options.hostname != NULL) { /* NB. Please keep in sync with readconf.c:match_cfg_line() */ cp = percent_expand(options.hostname, "h", host, (char *)NULL); free(host); host = cp; free(options.hostname); options.hostname = xstrdup(host); } /* If canonicalization requested then try to apply it */ lowercase(host); if (options.canonicalize_hostname != SSH_CANONICALISE_NO) addrs = resolve_canonicalize(&host, options.port); /* * If CanonicalizePermittedCNAMEs have been specified but * other canonicalization did not happen (by not being requested * or by failing with fallback) then the hostname may still be changed * as a result of CNAME following. * * Try to resolve the bare hostname name using the system resolver's * usual search rules and then apply the CNAME follow rules. * * Skip the lookup if a ProxyCommand is being used unless the user * has specifically requested canonicalisation for this case via * CanonicalizeHostname=always */ if (addrs == NULL && options.num_permitted_cnames != 0 && (option_clear_or_none(options.proxy_command) || options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { if ((addrs = resolve_host(host, options.port, option_clear_or_none(options.proxy_command), cname, sizeof(cname))) == NULL) { /* Don't fatal proxied host names not in the DNS */ if (option_clear_or_none(options.proxy_command)) cleanup_exit(255); /* logged in resolve_host */ } else check_follow_cname(&host, cname); } /* * If canonicalisation is enabled then re-parse the configuration * files as new stanzas may match. */ if (options.canonicalize_hostname != 0) { debug("Re-reading configuration after hostname " "canonicalisation"); free(options.hostname); options.hostname = xstrdup(host); process_config_files(host_arg, pw, 1); /* * Address resolution happens early with canonicalisation * enabled and the port number may have changed since, so * reset it in address list */ if (addrs != NULL && options.port > 0) set_addrinfo_port(addrs, options.port); } /* Fill configuration defaults. */ fill_default_options(&options); if (options.port == 0) options.port = default_ssh_port(); channel_set_af(options.address_family); /* Tidy and check options */ if (options.host_key_alias != NULL) lowercase(options.host_key_alias); if (options.proxy_command != NULL && strcmp(options.proxy_command, "-") == 0 && options.proxy_use_fdpass) fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); if (options.control_persist && options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { debug("UpdateHostKeys=ask is incompatible with ControlPersist; " "disabling"); options.update_hostkeys = 0; } if (options.connection_attempts <= 0) fatal("Invalid number of ConnectionAttempts"); #ifndef HAVE_CYGWIN if (original_effective_uid != 0) options.use_privileged_port = 0; #endif /* reinit */ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); if (options.request_tty == REQUEST_TTY_YES || options.request_tty == REQUEST_TTY_FORCE) tty_flag = 1; /* Allocate a tty by default if no command specified. */ if (buffer_len(&command) == 0) tty_flag = options.request_tty != REQUEST_TTY_NO; /* Force no tty */ if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ if ((!isatty(fileno(stdin)) || stdin_null_flag) && options.request_tty != REQUEST_TTY_FORCE) { if (tty_flag) logit("Pseudo-terminal will not be allocated because " "stdin is not a terminal."); tty_flag = 0; } seed_rng(); if (options.user == NULL) options.user = xstrdup(pw->pw_name); if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); strlcpy(shorthost, thishost, sizeof(shorthost)); shorthost[strcspn(thishost, ".")] = '\0'; snprintf(portstr, sizeof(portstr), "%d", options.port); snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid); if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || ssh_digest_update(md, thishost, strlen(thishost)) < 0 || ssh_digest_update(md, host, strlen(host)) < 0 || ssh_digest_update(md, portstr, strlen(portstr)) < 0 || ssh_digest_update(md, options.user, strlen(options.user)) < 0 || ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0) fatal("%s: mux digest failed", __func__); ssh_digest_free(md); conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); if (options.local_command != NULL) { debug3("expanding LocalCommand: %s", options.local_command); cp = options.local_command; options.local_command = percent_expand(cp, "C", conn_hash_hex, "L", shorthost, "d", pw->pw_dir, "h", host, "l", thishost, "n", host_arg, "p", portstr, "r", options.user, "u", pw->pw_name, (char *)NULL); debug3("expanded LocalCommand: %s", options.local_command); free(cp); } if (options.control_path != NULL) { cp = tilde_expand_filename(options.control_path, original_real_uid); free(options.control_path); options.control_path = percent_expand(cp, "C", conn_hash_hex, "L", shorthost, "h", host, "l", thishost, "n", host_arg, "p", portstr, "r", options.user, "u", pw->pw_name, "i", uidstr, (char *)NULL); free(cp); } free(conn_hash_hex); if (config_test) { dump_client_config(&options, host); exit(0); } if (muxclient_command != 0 && options.control_path == NULL) fatal("No ControlPath specified for \"-O\" command"); if (options.control_path != NULL) muxclient(options.control_path); /* * If hostname canonicalisation was not enabled, then we may not * have yet resolved the hostname. Do so now. */ if (addrs == NULL && options.proxy_command == NULL) { debug2("resolving \"%s\" port %d", host, options.port); if ((addrs = resolve_host(host, options.port, 1, cname, sizeof(cname))) == NULL) cleanup_exit(255); /* resolve_host logs the error */ } timeout_ms = options.connection_timeout * 1000; /* Open a connection to the remote host. */ if (ssh_connect(host, addrs, &hostaddr, options.port, options.address_family, options.connection_attempts, &timeout_ms, options.tcp_keep_alive, options.use_privileged_port) != 0) exit(255); if (addrs != NULL) freeaddrinfo(addrs); packet_set_timeout(options.server_alive_interval, options.server_alive_count_max); if (timeout_ms > 0) debug3("timeout: %d ms remain after connect", timeout_ms); /* * If we successfully made the connection, load the host private key * in case we will need it later for combined rsa-rhosts * authentication. This must be done before releasing extra * privileges, because the file is only readable by root. * If we cannot access the private keys, load the public keys * instead and try to execute the ssh-keysign helper instead. */ sensitive_data.nkeys = 0; sensitive_data.keys = NULL; sensitive_data.external_keysign = 0; if (options.rhosts_rsa_authentication || options.hostbased_authentication) { sensitive_data.nkeys = 9; sensitive_data.keys = xcalloc(sensitive_data.nkeys, sizeof(Key)); for (i = 0; i < sensitive_data.nkeys; i++) sensitive_data.keys[i] = NULL; PRIV_START; #if WITH_SSH1 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL, NULL); #endif #ifdef OPENSSL_HAS_ECC sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL); #endif sensitive_data.keys[2] = key_load_private_cert(KEY_ED25519, _PATH_HOST_ED25519_KEY_FILE, "", NULL); sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); sensitive_data.keys[4] = key_load_private_cert(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL); #ifdef OPENSSL_HAS_ECC sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); #endif sensitive_data.keys[6] = key_load_private_type(KEY_ED25519, _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); sensitive_data.keys[7] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); sensitive_data.keys[8] = key_load_private_type(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); PRIV_END; if (options.hostbased_authentication == 1 && sensitive_data.keys[0] == NULL && sensitive_data.keys[5] == NULL && sensitive_data.keys[6] == NULL && sensitive_data.keys[7] == NULL && sensitive_data.keys[8] == NULL) { #ifdef OPENSSL_HAS_ECC sensitive_data.keys[1] = key_load_cert( _PATH_HOST_ECDSA_KEY_FILE); #endif sensitive_data.keys[2] = key_load_cert( _PATH_HOST_ED25519_KEY_FILE); sensitive_data.keys[3] = key_load_cert( _PATH_HOST_RSA_KEY_FILE); sensitive_data.keys[4] = key_load_cert( _PATH_HOST_DSA_KEY_FILE); #ifdef OPENSSL_HAS_ECC sensitive_data.keys[5] = key_load_public( _PATH_HOST_ECDSA_KEY_FILE, NULL); #endif sensitive_data.keys[6] = key_load_public( _PATH_HOST_ED25519_KEY_FILE, NULL); sensitive_data.keys[7] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); sensitive_data.keys[8] = key_load_public( _PATH_HOST_DSA_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } } /* * Get rid of any extra privileges that we may have. We will no * longer need them. Also, extra privileges could make it very hard * to read identity files and other non-world-readable files from the * user's home directory if it happens to be on a NFS volume where * root is mapped to nobody. */ if (original_effective_uid == 0) { PRIV_START; permanently_set_uid(pw); } /* * Now that we are back to our own permissions, create ~/.ssh * directory if it doesn't already exist. */ if (config == NULL) { r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) { #ifdef WITH_SELINUX ssh_selinux_setfscreatecon(buf); #endif if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); #ifdef WITH_SELINUX ssh_selinux_setfscreatecon(NULL); #endif } } /* load options.identity_files */ load_public_identity_files(); /* Expand ~ in known host file names. */ tilde_expand_paths(options.system_hostfiles, options.num_system_hostfiles); tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles); signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ signal(SIGCHLD, main_sigchld_handler); /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, options.port, pw, timeout_ms); if (packet_connection_is_on_socket()) { verbose("Authenticated to %s ([%s]:%d).", host, get_remote_ipaddr(), get_remote_port()); } else { verbose("Authenticated to %s (via proxy).", host); } /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { if (sensitive_data.keys[i] != NULL) { /* Destroys contents safely */ debug3("clear hostkey %d", i); key_free(sensitive_data.keys[i]); sensitive_data.keys[i] = NULL; } } free(sensitive_data.keys); } for (i = 0; i < options.num_identity_files; i++) { free(options.identity_files[i]); options.identity_files[i] = NULL; if (options.identity_keys[i]) { key_free(options.identity_keys[i]); options.identity_keys[i] = NULL; } } for (i = 0; i < options.num_certificate_files; i++) { free(options.certificate_files[i]); options.certificate_files[i] = NULL; } exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); /* Kill ProxyCommand if it is running. */ ssh_kill_proxy_command(); return exit_status; } static void control_persist_detach(void) { pid_t pid; int devnull; debug("%s: backgrounding master process", __func__); /* * master (current process) into the background, and make the * foreground process a client of the backgrounded master. */ switch ((pid = fork())) { case -1: fatal("%s: fork: %s", __func__, strerror(errno)); case 0: /* Child: master process continues mainloop */ break; default: /* Parent: set up mux slave to connect to backgrounded master */ debug2("%s: background process is %ld", __func__, (long)pid); stdin_null_flag = ostdin_null_flag; options.request_tty = orequest_tty; tty_flag = otty_flag; close(muxserver_sock); muxserver_sock = -1; options.control_master = SSHCTL_MASTER_NO; muxclient(options.control_path); /* muxclient() doesn't return on success. */ fatal("Failed to connect to new control master"); } if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { error("%s: open(\"/dev/null\"): %s", __func__, strerror(errno)); } else { if (dup2(devnull, STDIN_FILENO) == -1 || dup2(devnull, STDOUT_FILENO) == -1) error("%s: dup2: %s", __func__, strerror(errno)); if (devnull > STDERR_FILENO) close(devnull); } daemon(1, 1); setproctitle("%s [mux]", options.control_path); } /* Do fork() after authentication. Used by "ssh -f" */ static void fork_postauth(void) { if (need_controlpersist_detach) control_persist_detach(); debug("forking to background"); fork_after_authentication_flag = 0; if (daemon(1, 1) < 0) fatal("daemon() failed: %.200s", strerror(errno)); } /* Callback for remote forward global requests */ static void ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) { struct Forward *rfwd = (struct Forward *)ctxt; /* XXX verbose() on failure? */ debug("remote forward %s for: listen %s%s%d, connect %s:%d", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", rfwd->listen_path ? rfwd->listen_path : rfwd->listen_host ? rfwd->listen_host : "", (rfwd->listen_path || rfwd->listen_host) ? ":" : "", rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : rfwd->connect_host, rfwd->connect_port); if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { if (type == SSH2_MSG_REQUEST_SUCCESS) { rfwd->allocated_port = packet_get_int(); logit("Allocated port %u for remote forward to %s:%d", rfwd->allocated_port, rfwd->connect_host, rfwd->connect_port); channel_update_permitted_opens(rfwd->handle, rfwd->allocated_port); } else { channel_update_permitted_opens(rfwd->handle, -1); } } if (type == SSH2_MSG_REQUEST_FAILURE) { if (options.exit_on_forward_failure) { if (rfwd->listen_path != NULL) fatal("Error: remote port forwarding failed " "for listen path %s", rfwd->listen_path); else fatal("Error: remote port forwarding failed " "for listen port %d", rfwd->listen_port); } else { if (rfwd->listen_path != NULL) logit("Warning: remote port forwarding failed " "for listen path %s", rfwd->listen_path); else logit("Warning: remote port forwarding failed " "for listen port %d", rfwd->listen_port); } } if (++remote_forward_confirms_received == options.num_remote_forwards) { debug("All remote forwarding requests processed"); if (fork_after_authentication_flag) fork_postauth(); } } static void client_cleanup_stdio_fwd(int id, void *arg) { debug("stdio forwarding: done"); cleanup_exit(0); } static void ssh_stdio_confirm(int id, int success, void *arg) { if (!success) fatal("stdio forwarding failed"); } static void ssh_init_stdio_forwarding(void) { Channel *c; int in, out; if (stdio_forward_host == NULL) return; if (!compat20) fatal("stdio forwarding require Protocol 2"); debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); if ((in = dup(STDIN_FILENO)) < 0 || (out = dup(STDOUT_FILENO)) < 0) fatal("channel_connect_stdio_fwd: dup() in/out failed"); if ((c = channel_connect_stdio_fwd(stdio_forward_host, stdio_forward_port, in, out)) == NULL) fatal("%s: channel_connect_stdio_fwd failed", __func__); channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); } static void ssh_init_forwarding(void) { int success = 0; int i; /* Initiate local TCP/IP port forwardings. */ for (i = 0; i < options.num_local_forwards; i++) { debug("Local connections to %.200s:%d forwarded to remote " "address %.200s:%d", (options.local_forwards[i].listen_path != NULL) ? options.local_forwards[i].listen_path : (options.local_forwards[i].listen_host == NULL) ? (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : options.local_forwards[i].listen_host, options.local_forwards[i].listen_port, (options.local_forwards[i].connect_path != NULL) ? options.local_forwards[i].connect_path : options.local_forwards[i].connect_host, options.local_forwards[i].connect_port); success += channel_setup_local_fwd_listener( &options.local_forwards[i], &options.fwd_opts); } if (i > 0 && success != i && options.exit_on_forward_failure) fatal("Could not request local forwarding."); if (i > 0 && success == 0) error("Could not request local forwarding."); /* Initiate remote TCP/IP port forwardings. */ for (i = 0; i < options.num_remote_forwards; i++) { debug("Remote connections from %.200s:%d forwarded to " "local address %.200s:%d", (options.remote_forwards[i].listen_path != NULL) ? options.remote_forwards[i].listen_path : (options.remote_forwards[i].listen_host == NULL) ? "LOCALHOST" : options.remote_forwards[i].listen_host, options.remote_forwards[i].listen_port, (options.remote_forwards[i].connect_path != NULL) ? options.remote_forwards[i].connect_path : options.remote_forwards[i].connect_host, options.remote_forwards[i].connect_port); options.remote_forwards[i].handle = channel_request_remote_forwarding( &options.remote_forwards[i]); if (options.remote_forwards[i].handle < 0) { if (options.exit_on_forward_failure) fatal("Could not request remote forwarding."); else logit("Warning: Could not request remote " "forwarding."); } else { client_register_global_confirm(ssh_confirm_remote_forward, &options.remote_forwards[i]); } } /* Initiate tunnel forwarding. */ if (options.tun_open != SSH_TUNMODE_NO) { if (client_request_tun_fwd(options.tun_open, options.tun_local, options.tun_remote) == -1) { if (options.exit_on_forward_failure) fatal("Could not request tunnel forwarding."); else error("Could not request tunnel forwarding."); } } } static void check_agent_present(void) { int r; if (options.forward_agent) { /* Clear agent forwarding if we don't have an agent. */ if ((r = ssh_get_authentication_socket(NULL)) != 0) { options.forward_agent = 0; if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("ssh_get_authentication_socket: %s", ssh_err(r)); } } } static int ssh_session(void) { int type; int interactive = 0; int have_tty = 0; struct winsize ws; char *cp; const char *display; char *proto = NULL, *data = NULL; /* Enable compression if requested. */ if (options.compression) { debug("Requesting compression at level %d.", options.compression_level); if (options.compression_level < 1 || options.compression_level > 9) fatal("Compression level must be from 1 (fast) to " "9 (slow, best)."); /* Send the request. */ packet_start(SSH_CMSG_REQUEST_COMPRESSION); packet_put_int(options.compression_level); packet_send(); packet_write_wait(); type = packet_read(); if (type == SSH_SMSG_SUCCESS) packet_start_compression(options.compression_level); else if (type == SSH_SMSG_FAILURE) logit("Warning: Remote host refused compression."); else packet_disconnect("Protocol error waiting for " "compression response."); } /* Allocate a pseudo tty if appropriate. */ if (tty_flag) { debug("Requesting pty."); /* Start the packet. */ packet_start(SSH_CMSG_REQUEST_PTY); /* Store TERM in the packet. There is no limit on the length of the string. */ cp = getenv("TERM"); if (!cp) cp = ""; packet_put_cstring(cp); /* Store window size in the packet. */ if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) memset(&ws, 0, sizeof(ws)); packet_put_int((u_int)ws.ws_row); packet_put_int((u_int)ws.ws_col); packet_put_int((u_int)ws.ws_xpixel); packet_put_int((u_int)ws.ws_ypixel); /* Store tty modes in the packet. */ tty_make_modes(fileno(stdin), NULL); /* Send the packet, and wait for it to leave. */ packet_send(); packet_write_wait(); /* Read response from the server. */ type = packet_read(); if (type == SSH_SMSG_SUCCESS) { interactive = 1; have_tty = 1; } else if (type == SSH_SMSG_FAILURE) logit("Warning: Remote host failed or refused to " "allocate a pseudo tty."); else packet_disconnect("Protocol error waiting for pty " "request response."); } /* Request X11 forwarding if enabled and DISPLAY is set. */ display = getenv("DISPLAY"); if (display == NULL && options.forward_x11) debug("X11 forwarding requested but DISPLAY not set"); if (options.forward_x11 && client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, options.forward_x11_timeout, &proto, &data) == 0) { /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication " "spoofing."); x11_request_forwarding_with_spoofing(0, display, proto, data, 0); /* Read response from the server. */ type = packet_read(); if (type == SSH_SMSG_SUCCESS) { interactive = 1; } else if (type == SSH_SMSG_FAILURE) { logit("Warning: Remote host denied X11 forwarding."); } else { packet_disconnect("Protocol error waiting for X11 " "forwarding"); } } /* Tell the packet module whether this is an interactive session. */ packet_set_interactive(interactive, options.ip_qos_interactive, options.ip_qos_bulk); /* Request authentication agent forwarding if appropriate. */ check_agent_present(); if (options.forward_agent) { debug("Requesting authentication agent forwarding."); auth_request_forwarding(); /* Read response from the server. */ type = packet_read(); packet_check_eom(); if (type != SSH_SMSG_SUCCESS) logit("Warning: Remote host denied authentication agent forwarding."); } /* Initiate port forwardings. */ ssh_init_stdio_forwarding(); ssh_init_forwarding(); /* Execute a local command */ if (options.local_command != NULL && options.permit_local_command) ssh_local_cmd(options.local_command); /* * If requested and we are not interested in replies to remote * forwarding requests, then let ssh continue in the background. */ if (fork_after_authentication_flag) { if (options.exit_on_forward_failure && options.num_remote_forwards > 0) { debug("deferring postauth fork until remote forward " "confirmation received"); } else fork_postauth(); } /* * If a command was specified on the command line, execute the * command now. Otherwise request the server to start a shell. */ if (buffer_len(&command) > 0) { int len = buffer_len(&command); if (len > 900) len = 900; debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); packet_start(SSH_CMSG_EXEC_CMD); packet_put_string(buffer_ptr(&command), buffer_len(&command)); packet_send(); packet_write_wait(); } else { debug("Requesting shell."); packet_start(SSH_CMSG_EXEC_SHELL); packet_send(); packet_write_wait(); } /* Enter the interactive session. */ return client_loop(have_tty, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, 0); } /* request pty/x11/agent/tcpfwd/shell for channel */ static void ssh_session2_setup(int id, int success, void *arg) { extern char **environ; const char *display; int interactive = tty_flag; char *proto = NULL, *data = NULL; if (!success) return; /* No need for error message, channels code sens one */ display = getenv("DISPLAY"); if (display == NULL && options.forward_x11) debug("X11 forwarding requested but DISPLAY not set"); if (options.forward_x11 && client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, options.forward_x11_timeout, &proto, &data) == 0) { /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication " "spoofing."); x11_request_forwarding_with_spoofing(id, display, proto, data, 1); client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); /* XXX exit_on_forward_failure */ interactive = 1; } check_agent_present(); if (options.forward_agent) { debug("Requesting authentication agent forwarding."); channel_request_start(id, "auth-agent-req@openssh.com", 0); packet_send(); } /* Tell the packet module whether this is an interactive session. */ packet_set_interactive(interactive, options.ip_qos_interactive, options.ip_qos_bulk); client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), NULL, fileno(stdin), &command, environ); } /* open new channel for a session */ static int ssh_session2_open(void) { Channel *c; int window, packetmax, in, out, err; if (stdin_null_flag) { in = open(_PATH_DEVNULL, O_RDONLY); } else { in = dup(STDIN_FILENO); } out = dup(STDOUT_FILENO); err = dup(STDERR_FILENO); if (in < 0 || out < 0 || err < 0) fatal("dup() in/out/err failed"); /* enable nonblocking unless tty */ if (!isatty(in)) set_nonblock(in); if (!isatty(out)) set_nonblock(out); if (!isatty(err)) set_nonblock(err); window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { window >>= 1; packetmax >>= 1; } c = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); if (!no_shell_flag) channel_register_open_confirm(c->self, ssh_session2_setup, NULL); return c->self; } static int ssh_session2(void) { int id = -1; /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(); ssh_init_forwarding(); /* Start listening for multiplex clients */ muxserver_listen(); /* * If we are in control persist mode and have a working mux listen * socket, then prepare to background ourselves and have a foreground * client attach as a control slave. * NB. we must save copies of the flags that we override for * the backgrounding, since we defer attachment of the slave until * after the connection is fully established (in particular, * async rfwd replies have been received for ExitOnForwardFailure). */ if (options.control_persist && muxserver_sock != -1) { ostdin_null_flag = stdin_null_flag; ono_shell_flag = no_shell_flag; orequest_tty = options.request_tty; otty_flag = tty_flag; stdin_null_flag = 1; no_shell_flag = 1; tty_flag = 0; if (!fork_after_authentication_flag) need_controlpersist_detach = 1; fork_after_authentication_flag = 1; } /* * ControlPersist mux listen socket setup failed, attempt the * stdio forward setup that we skipped earlier. */ if (options.control_persist && muxserver_sock == -1) ssh_init_stdio_forwarding(); if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); else { packet_set_interactive( options.control_master == SSHCTL_MASTER_NO, options.ip_qos_interactive, options.ip_qos_bulk); } /* If we don't expect to open a new session, then disallow it */ if (options.control_master == SSHCTL_MASTER_NO && (datafellows & SSH_NEW_OPENSSH)) { debug("Requesting no-more-sessions@openssh.com"); packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("no-more-sessions@openssh.com"); packet_put_char(0); packet_send(); } /* Execute a local command */ if (options.local_command != NULL && options.permit_local_command) ssh_local_cmd(options.local_command); /* * If requested and we are not interested in replies to remote * forwarding requests, then let ssh continue in the background. */ if (fork_after_authentication_flag) { if (options.exit_on_forward_failure && options.num_remote_forwards > 0) { debug("deferring postauth fork until remote forward " "confirmation received"); } else fork_postauth(); } return client_loop(tty_flag, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, id); } /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(void) { char *filename, *cp, thishost[NI_MAXHOST]; char *pwdir = NULL, *pwname = NULL; Key *public; struct passwd *pw; int i; u_int n_ids, n_certs; char *identity_files[SSH_MAX_IDENTITY_FILES]; Key *identity_keys[SSH_MAX_IDENTITY_FILES]; char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; #ifdef ENABLE_PKCS11 Key **keys; int nkeys; #endif /* PKCS11 */ n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); memset(identity_keys, 0, sizeof(identity_keys)); memset(certificate_files, 0, sizeof(certificate_files)); memset(certificates, 0, sizeof(certificates)); #ifdef ENABLE_PKCS11 if (options.pkcs11_provider != NULL && options.num_identity_files < SSH_MAX_IDENTITY_FILES && (pkcs11_init(!options.batch_mode) == 0) && (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, &keys)) > 0) { for (i = 0; i < nkeys; i++) { if (n_ids >= SSH_MAX_IDENTITY_FILES) { key_free(keys[i]); continue; } identity_keys[n_ids] = keys[i]; identity_files[n_ids] = xstrdup(options.pkcs11_provider); /* XXX */ n_ids++; } free(keys); } #endif /* ENABLE_PKCS11 */ if ((pw = getpwuid(original_real_uid)) == NULL) fatal("load_public_identity_files: getpwuid failed"); pwname = xstrdup(pw->pw_name); pwdir = xstrdup(pw->pw_dir); if (gethostname(thishost, sizeof(thishost)) == -1) fatal("load_public_identity_files: gethostname: %s", strerror(errno)); for (i = 0; i < options.num_identity_files; i++) { if (n_ids >= SSH_MAX_IDENTITY_FILES || strcasecmp(options.identity_files[i], "none") == 0) { free(options.identity_files[i]); options.identity_files[i] = NULL; continue; } cp = tilde_expand_filename(options.identity_files[i], original_real_uid); filename = percent_expand(cp, "d", pwdir, "u", pwname, "l", thishost, "h", host, "r", options.user, (char *)NULL); free(cp); public = key_load_public(filename, NULL); debug("identity file %s type %d", filename, public ? public->type : -1); free(options.identity_files[i]); identity_files[n_ids] = filename; identity_keys[n_ids] = public; if (++n_ids >= SSH_MAX_IDENTITY_FILES) continue; /* * If no certificates have been explicitly listed then try * to add the default certificate variant too. */ if (options.num_certificate_files != 0) continue; xasprintf(&cp, "%s-cert", filename); public = key_load_public(cp, NULL); debug("identity file %s type %d", cp, public ? public->type : -1); if (public == NULL) { free(cp); continue; } if (!key_is_cert(public)) { debug("%s: key %s type %s is not a certificate", __func__, cp, key_type(public)); key_free(public); free(cp); continue; } identity_keys[n_ids] = public; identity_files[n_ids] = cp; n_ids++; } if (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES) fatal("%s: too many certificates", __func__); for (i = 0; i < options.num_certificate_files; i++) { cp = tilde_expand_filename(options.certificate_files[i], original_real_uid); filename = percent_expand(cp, "d", pwdir, "u", pwname, "l", thishost, "h", host, "r", options.user, (char *)NULL); free(cp); public = key_load_public(filename, NULL); debug("certificate file %s type %d", filename, public ? public->type : -1); free(options.certificate_files[i]); options.certificate_files[i] = NULL; if (public == NULL) { free(filename); continue; } if (!key_is_cert(public)) { debug("%s: key %s type %s is not a certificate", __func__, filename, key_type(public)); key_free(public); free(filename); continue; } certificate_files[n_certs] = filename; certificates[n_certs] = public; ++n_certs; } options.num_identity_files = n_ids; memcpy(options.identity_files, identity_files, sizeof(identity_files)); memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); options.num_certificate_files = n_certs; memcpy(options.certificate_files, certificate_files, sizeof(certificate_files)); memcpy(options.certificates, certificates, sizeof(certificates)); explicit_bzero(pwname, strlen(pwname)); free(pwname); explicit_bzero(pwdir, strlen(pwdir)); free(pwdir); } static void main_sigchld_handler(int sig) { int save_errno = errno; pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) ; signal(sig, main_sigchld_handler); errno = save_errno; } openssh-7.2p2/ssh.h010064400017500001750000000056231267006270000124260ustar00djmdjm/* $OpenBSD: ssh.h,v 1.83 2015/12/11 03:19:09 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ /* Cipher used for encrypting authentication files. */ #define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES /* Default port number. */ #define SSH_DEFAULT_PORT 22 /* * Maximum number of certificate files that can be specified * in configuration files or on the command line. */ #define SSH_MAX_CERTIFICATE_FILES 100 /* * Maximum number of RSA authentication identity files that can be specified * in configuration files or on the command line. */ #define SSH_MAX_IDENTITY_FILES 100 /* * Maximum length of lines in authorized_keys file. * Current value permits 16kbit RSA and RSA1 keys and 8kbit DSA keys, with * some room for options and comments. */ #define SSH_MAX_PUBKEY_BYTES 16384 /* * Major protocol version. Different version indicates major incompatibility * that prevents communication. * * Minor protocol version. Different version indicates minor incompatibility * that does not prevent interoperation. */ #define PROTOCOL_MAJOR_1 1 #define PROTOCOL_MINOR_1 5 /* We support both SSH1 and SSH2 */ #define PROTOCOL_MAJOR_2 2 #define PROTOCOL_MINOR_2 0 /* * Name for the service. The port named by this service overrides the * default port if present. */ #define SSH_SERVICE_NAME "ssh" /* * Name of the environment variable containing the process ID of the * authentication agent. */ #define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" /* * Name of the environment variable containing the pathname of the * authentication socket. */ #define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" /* * Environment variable for overwriting the default location of askpass */ #define SSH_ASKPASS_ENV "SSH_ASKPASS" /* * Force host key length and server key length to differ by at least this * many bits. This is to make double encryption with rsaref work. */ #define SSH_KEY_BITS_RESERVED 128 /* * Length of the session key in bytes. (Specified as 256 bits in the * protocol.) */ #define SSH_SESSION_KEY_LENGTH 32 /* Used to identify ``EscapeChar none'' */ #define SSH_ESCAPECHAR_NONE -2 /* * unprivileged user when UsePrivilegeSeparation=yes; * sshd will change its privileges to this user and its * primary group. */ #ifndef SSH_PRIVSEP_USER #define SSH_PRIVSEP_USER "sshd" #endif /* Minimum modulus size (n) for RSA keys. */ #define SSH_RSA_MINIMUM_MODULUS_SIZE 768 /* Listen backlog for sshd, ssh-agent and forwarding sockets */ #define SSH_LISTEN_BACKLOG 128 openssh-7.2p2/ssh1.h010064400017500001750000000101511267006270000124770ustar00djmdjm/* $OpenBSD: ssh1.h,v 1.6 2006/03/25 22:22:43 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ /* * Definition of message types. New values can be added, but old values * should not be removed or without careful consideration of the consequences * for compatibility. The maximum value is 254; value 255 is reserved for * future extension. */ /* Ranges */ #define SSH_MSG_MIN 1 #define SSH_MSG_MAX 254 /* Message name */ /* msg code */ /* arguments */ #define SSH_MSG_NONE 0 /* no message */ #define SSH_MSG_DISCONNECT 1 /* cause (string) */ #define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ #define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ #define SSH_CMSG_USER 4 /* user (string) */ #define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ #define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ #define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ #define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ #define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ #define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ #define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ #define SSH_CMSG_EXEC_SHELL 12 /* */ #define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ #define SSH_SMSG_SUCCESS 14 /* */ #define SSH_SMSG_FAILURE 15 /* */ #define SSH_CMSG_STDIN_DATA 16 /* data (string) */ #define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ #define SSH_SMSG_STDERR_DATA 18 /* data (string) */ #define SSH_CMSG_EOF 19 /* */ #define SSH_SMSG_EXITSTATUS 20 /* status (int) */ #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ #define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ #define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ #define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ #define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ /* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ #define SSH_SMSG_X11_OPEN 27 /* channel (int) */ #define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ #define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ #define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ #define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ #define SSH_MSG_IGNORE 32 /* string */ #define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ #define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ #define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ #define SSH_MSG_DEBUG 36 /* string */ #define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ #define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ #define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ #define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ #define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ #define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ #define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ #define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ #define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ /* protocol version 1.5 overloads some version 1.3 message types */ #define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE #define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION /* * Authentication methods. New types can be added, but old types should not * be removed for compatibility. The maximum allowed value is 31. */ #define SSH_AUTH_RHOSTS 1 #define SSH_AUTH_RSA 2 #define SSH_AUTH_PASSWORD 3 #define SSH_AUTH_RHOSTS_RSA 4 #define SSH_AUTH_TIS 5 #define SSH_AUTH_KERBEROS 6 #define SSH_PASS_KERBEROS_TGT 7 /* 8 to 15 are reserved */ #define SSH_PASS_AFS_TOKEN 21 /* Protocol flags. These are bit masks. */ #define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ #define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ openssh-7.2p2/ssh2.h010064400017500001750000000131451267006270000125060ustar00djmdjm/* $OpenBSD: ssh2.h,v 1.17 2016/01/14 16:17:40 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. */ /* * draft-ietf-secsh-architecture-05.txt * * Transport layer protocol: * * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, * etc) * 20-29 Algorithm negotiation * 30-49 Key exchange method specific (numbers can be reused for * different authentication methods) * * User authentication protocol: * * 50-59 User authentication generic * 60-79 User authentication method specific (numbers can be reused * for different authentication methods) * * Connection protocol: * * 80-89 Connection protocol generic * 90-127 Channel related messages * * Reserved for client protocols: * * 128-191 Reserved * * Local extensions: * * 192-255 Local extensions */ /* ranges */ #define SSH2_MSG_TRANSPORT_MIN 1 #define SSH2_MSG_TRANSPORT_MAX 49 #define SSH2_MSG_USERAUTH_MIN 50 #define SSH2_MSG_USERAUTH_MAX 79 #define SSH2_MSG_USERAUTH_PER_METHOD_MIN 60 #define SSH2_MSG_USERAUTH_PER_METHOD_MAX SSH2_MSG_USERAUTH_MAX #define SSH2_MSG_CONNECTION_MIN 80 #define SSH2_MSG_CONNECTION_MAX 127 #define SSH2_MSG_RESERVED_MIN 128 #define SSH2_MSG_RESERVED_MAX 191 #define SSH2_MSG_LOCAL_MIN 192 #define SSH2_MSG_LOCAL_MAX 255 #define SSH2_MSG_MIN 1 #define SSH2_MSG_MAX 255 /* transport layer: generic */ #define SSH2_MSG_DISCONNECT 1 #define SSH2_MSG_IGNORE 2 #define SSH2_MSG_UNIMPLEMENTED 3 #define SSH2_MSG_DEBUG 4 #define SSH2_MSG_SERVICE_REQUEST 5 #define SSH2_MSG_SERVICE_ACCEPT 6 #define SSH2_MSG_EXT_INFO 7 /* transport layer: alg negotiation */ #define SSH2_MSG_KEXINIT 20 #define SSH2_MSG_NEWKEYS 21 /* transport layer: kex specific messages, can be reused */ #define SSH2_MSG_KEXDH_INIT 30 #define SSH2_MSG_KEXDH_REPLY 31 /* dh-group-exchange */ #define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30 #define SSH2_MSG_KEX_DH_GEX_GROUP 31 #define SSH2_MSG_KEX_DH_GEX_INIT 32 #define SSH2_MSG_KEX_DH_GEX_REPLY 33 #define SSH2_MSG_KEX_DH_GEX_REQUEST 34 /* ecdh */ #define SSH2_MSG_KEX_ECDH_INIT 30 #define SSH2_MSG_KEX_ECDH_REPLY 31 /* user authentication: generic */ #define SSH2_MSG_USERAUTH_REQUEST 50 #define SSH2_MSG_USERAUTH_FAILURE 51 #define SSH2_MSG_USERAUTH_SUCCESS 52 #define SSH2_MSG_USERAUTH_BANNER 53 /* user authentication: method specific, can be reused */ #define SSH2_MSG_USERAUTH_PK_OK 60 #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 #define SSH2_MSG_USERAUTH_INFO_REQUEST 60 #define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 /* connection protocol: generic */ #define SSH2_MSG_GLOBAL_REQUEST 80 #define SSH2_MSG_REQUEST_SUCCESS 81 #define SSH2_MSG_REQUEST_FAILURE 82 /* channel related messages */ #define SSH2_MSG_CHANNEL_OPEN 90 #define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 #define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 #define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 #define SSH2_MSG_CHANNEL_DATA 94 #define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 #define SSH2_MSG_CHANNEL_EOF 96 #define SSH2_MSG_CHANNEL_CLOSE 97 #define SSH2_MSG_CHANNEL_REQUEST 98 #define SSH2_MSG_CHANNEL_SUCCESS 99 #define SSH2_MSG_CHANNEL_FAILURE 100 /* disconnect reason code */ #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 #define SSH2_DISCONNECT_PROTOCOL_ERROR 2 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 #define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 #define SSH2_DISCONNECT_RESERVED 4 #define SSH2_DISCONNECT_MAC_ERROR 5 #define SSH2_DISCONNECT_COMPRESSION_ERROR 6 #define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 #define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 #define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 #define SSH2_DISCONNECT_CONNECTION_LOST 10 #define SSH2_DISCONNECT_BY_APPLICATION 11 #define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 #define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 #define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 #define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 /* misc */ #define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 #define SSH2_OPEN_CONNECT_FAILED 2 #define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 #define SSH2_OPEN_RESOURCE_SHORTAGE 4 #define SSH2_EXTENDED_DATA_STDERR 1 /* Certificate types for OpenSSH certificate keys extension */ #define SSH2_CERT_TYPE_USER 1 #define SSH2_CERT_TYPE_HOST 2 openssh-7.2p2/ssh_api.c010064400017500001750000000331241267006270000132470ustar00djmdjm/* $OpenBSD: ssh_api.c,v 1.5 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include "ssh1.h" /* For SSH_MSG_NONE */ #include "ssh_api.h" #include "compat.h" #include "log.h" #include "authfile.h" #include "sshkey.h" #include "misc.h" #include "ssh1.h" #include "ssh2.h" #include "version.h" #include "myproposal.h" #include "ssherr.h" #include "sshbuf.h" #include int _ssh_exchange_banner(struct ssh *); int _ssh_send_banner(struct ssh *, char **); int _ssh_read_banner(struct ssh *, char **); int _ssh_order_hostkeyalgs(struct ssh *); int _ssh_verify_host_key(struct sshkey *, struct ssh *); struct sshkey *_ssh_host_public_key(int, int, struct ssh *); struct sshkey *_ssh_host_private_key(int, int, struct ssh *); int _ssh_host_key_sign(struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); /* * stubs for the server side implementation of kex. * disable privsep so our stubs will never be called. */ int use_privsep = 0; int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, u_char *, u_int, char *, u_int); DH *mm_choose_dh(int, int, int); /* Define these two variables here so that they are part of the library */ u_char *session_id2 = NULL; u_int session_id2_len = 0; int mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen, char *alg, u_int compat) { return (-1); } DH * mm_choose_dh(int min, int nbits, int max) { return (NULL); } /* API */ int ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; struct ssh *ssh; char **proposal; static int called; int r; if (!called) { #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif /* WITH_OPENSSL */ called = 1; } if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL) return SSH_ERR_ALLOC_FAIL; if (is_server) ssh_packet_set_server(ssh); /* Initialize key exchange */ proposal = kex_params ? kex_params->proposal : myproposal; if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) { ssh_free(ssh); return r; } ssh->kex->server = is_server; if (is_server) { #ifdef WITH_OPENSSL ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; # endif #endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server; ssh->kex->load_host_public_key=&_ssh_host_public_key; ssh->kex->load_host_private_key=&_ssh_host_private_key; ssh->kex->sign=&_ssh_host_key_sign; } else { #ifdef WITH_OPENSSL ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; ssh->kex->verify_host_key =&_ssh_verify_host_key; } *sshp = ssh; return 0; } void ssh_free(struct ssh *ssh) { struct key_entry *k; ssh_packet_close(ssh); /* * we've only created the public keys variants in case we * are a acting as a server. */ while ((k = TAILQ_FIRST(&ssh->public_keys)) != NULL) { TAILQ_REMOVE(&ssh->public_keys, k, next); if (ssh->kex && ssh->kex->server) sshkey_free(k->key); free(k); } while ((k = TAILQ_FIRST(&ssh->private_keys)) != NULL) { TAILQ_REMOVE(&ssh->private_keys, k, next); free(k); } if (ssh->kex) kex_free(ssh->kex); free(ssh); } void ssh_set_app_data(struct ssh *ssh, void *app_data) { ssh->app_data = app_data; } void * ssh_get_app_data(struct ssh *ssh) { return ssh->app_data; } /* Returns < 0 on error, 0 otherwise */ int ssh_add_hostkey(struct ssh *ssh, struct sshkey *key) { struct sshkey *pubkey = NULL; struct key_entry *k = NULL, *k_prv = NULL; int r; if (ssh->kex->server) { if ((r = sshkey_from_private(key, &pubkey)) != 0) return r; if ((k = malloc(sizeof(*k))) == NULL || (k_prv = malloc(sizeof(*k_prv))) == NULL) { free(k); sshkey_free(pubkey); return SSH_ERR_ALLOC_FAIL; } k_prv->key = key; TAILQ_INSERT_TAIL(&ssh->private_keys, k_prv, next); /* add the public key, too */ k->key = pubkey; TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); r = 0; } else { if ((k = malloc(sizeof(*k))) == NULL) return SSH_ERR_ALLOC_FAIL; k->key = key; TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); r = 0; } return r; } int ssh_set_verify_host_key_callback(struct ssh *ssh, int (*cb)(struct sshkey *, struct ssh *)) { if (cb == NULL || ssh->kex == NULL) return SSH_ERR_INVALID_ARGUMENT; ssh->kex->verify_host_key = cb; return 0; } int ssh_input_append(struct ssh *ssh, const u_char *data, size_t len) { return sshbuf_put(ssh_packet_get_input(ssh), data, len); } int ssh_packet_next(struct ssh *ssh, u_char *typep) { int r; u_int32_t seqnr; u_char type; /* * Try to read a packet. Return SSH_MSG_NONE if no packet or not * enough data. */ *typep = SSH_MSG_NONE; if (ssh->kex->client_version_string == NULL || ssh->kex->server_version_string == NULL) return _ssh_exchange_banner(ssh); /* * If we enough data and a dispatch function then * call the function and get the next packet. * Otherwise return the packet type to the caller so it * can decide how to go on. * * We will only call the dispatch function for: * 20-29 Algorithm negotiation * 30-49 Key exchange method specific (numbers can be reused for * different authentication methods) */ for (;;) { if ((r = ssh_packet_read_poll2(ssh, &type, &seqnr)) != 0) return r; if (type > 0 && type < DISPATCH_MAX && type >= SSH2_MSG_KEXINIT && type <= SSH2_MSG_TRANSPORT_MAX && ssh->dispatch[type] != NULL) { if ((r = (*ssh->dispatch[type])(type, seqnr, ssh)) != 0) return r; } else { *typep = type; return 0; } } } const u_char * ssh_packet_payload(struct ssh *ssh, size_t *lenp) { return sshpkt_ptr(ssh, lenp); } int ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len) { int r; if ((r = sshpkt_start(ssh, type)) != 0 || (r = sshpkt_put(ssh, data, len)) != 0 || (r = sshpkt_send(ssh)) != 0) return r; return 0; } const u_char * ssh_output_ptr(struct ssh *ssh, size_t *len) { struct sshbuf *output = ssh_packet_get_output(ssh); *len = sshbuf_len(output); return sshbuf_ptr(output); } int ssh_output_consume(struct ssh *ssh, size_t len) { return sshbuf_consume(ssh_packet_get_output(ssh), len); } int ssh_output_space(struct ssh *ssh, size_t len) { return (0 == sshbuf_check_reserve(ssh_packet_get_output(ssh), len)); } int ssh_input_space(struct ssh *ssh, size_t len) { return (0 == sshbuf_check_reserve(ssh_packet_get_input(ssh), len)); } /* Read other side's version identification. */ int _ssh_read_banner(struct ssh *ssh, char **bannerp) { struct sshbuf *input; const char *s; char buf[256], remote_version[256]; /* must be same size! */ const char *mismatch = "Protocol mismatch.\r\n"; int r, remote_major, remote_minor; size_t i, n, j, len; *bannerp = NULL; input = ssh_packet_get_input(ssh); len = sshbuf_len(input); s = (const char *)sshbuf_ptr(input); for (j = n = 0;;) { for (i = 0; i < sizeof(buf) - 1; i++) { if (j >= len) return (0); buf[i] = s[j++]; if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; continue; /**XXX wait for \n */ } if (buf[i] == '\n') { buf[i + 1] = 0; break; } } buf[sizeof(buf) - 1] = 0; if (strncmp(buf, "SSH-", 4) == 0) break; debug("ssh_exchange_identification: %s", buf); if (ssh->kex->server || ++n > 65536) { if ((r = sshbuf_put(ssh_packet_get_output(ssh), mismatch, strlen(mismatch))) != 0) return r; return SSH_ERR_NO_PROTOCOL_VERSION; } } if ((r = sshbuf_consume(input, j)) != 0) return r; /* * Check that the versions match. In future this might accept * several versions and set appropriate flags to handle them. */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) return SSH_ERR_INVALID_FORMAT; debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); ssh->compat = compat_datafellows(remote_version); if (remote_major == 1 && remote_minor == 99) { remote_major = 2; remote_minor = 0; } if (remote_major != 2) return SSH_ERR_PROTOCOL_MISMATCH; enable_compat20(); chop(buf); debug("Remote version string %.100s", buf); if ((*bannerp = strdup(buf)) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } /* Send our own protocol version identification. */ int _ssh_send_banner(struct ssh *ssh, char **bannerp) { char buf[256]; int r; snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION); if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0) return r; chop(buf); debug("Local version string %.100s", buf); if ((*bannerp = strdup(buf)) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } int _ssh_exchange_banner(struct ssh *ssh) { struct kex *kex = ssh->kex; int r; /* * if _ssh_read_banner() cannot parse a full version string * it will return NULL and we end up calling it again. */ r = 0; if (kex->server) { if (kex->server_version_string == NULL) r = _ssh_send_banner(ssh, &kex->server_version_string); if (r == 0 && kex->server_version_string != NULL && kex->client_version_string == NULL) r = _ssh_read_banner(ssh, &kex->client_version_string); } else { if (kex->server_version_string == NULL) r = _ssh_read_banner(ssh, &kex->server_version_string); if (r == 0 && kex->server_version_string != NULL && kex->client_version_string == NULL) r = _ssh_send_banner(ssh, &kex->client_version_string); } if (r != 0) return r; /* start initial kex as soon as we have exchanged the banners */ if (kex->server_version_string != NULL && kex->client_version_string != NULL) { if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || (r = kex_send_kexinit(ssh)) != 0) return r; } return 0; } struct sshkey * _ssh_host_public_key(int type, int nid, struct ssh *ssh) { struct key_entry *k; debug3("%s: need %d", __func__, type); TAILQ_FOREACH(k, &ssh->public_keys, next) { debug3("%s: check %s", __func__, sshkey_type(k->key)); if (k->key->type == type && (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) return (k->key); } return (NULL); } struct sshkey * _ssh_host_private_key(int type, int nid, struct ssh *ssh) { struct key_entry *k; debug3("%s: need %d", __func__, type); TAILQ_FOREACH(k, &ssh->private_keys, next) { debug3("%s: check %s", __func__, sshkey_type(k->key)); if (k->key->type == type && (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) return (k->key); } return (NULL); } int _ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh) { struct key_entry *k; debug3("%s: need %s", __func__, sshkey_type(hostkey)); TAILQ_FOREACH(k, &ssh->public_keys, next) { debug3("%s: check %s", __func__, sshkey_type(k->key)); if (sshkey_equal_public(hostkey, k->key)) return (0); /* ok */ } return (-1); /* failed */ } /* offer hostkey algorithms in kexinit depending on registered keys */ int _ssh_order_hostkeyalgs(struct ssh *ssh) { struct key_entry *k; char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; char **proposal; size_t maxlen; int ktype, r; /* XXX we de-serialize ssh->kex->my, modify it, and change it */ if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) return r; orig = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; if ((oavail = avail = strdup(orig)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } maxlen = strlen(avail) + 1; if ((replace = calloc(1, maxlen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } *replace = '\0'; while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) continue; TAILQ_FOREACH(k, &ssh->public_keys, next) { if (k->key->type == ktype || (sshkey_is_cert(k->key) && k->key->type == sshkey_type_plain(ktype))) { if (*replace != '\0') strlcat(replace, ",", maxlen); strlcat(replace, alg, maxlen); break; } } } if (*replace != '\0') { debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig); debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace); free(orig); proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace; replace = NULL; /* owned by proposal */ r = kex_prop2buf(ssh->kex->my, proposal); } out: free(oavail); free(replace); kex_prop_free(proposal); return r; } int _ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey, u_char **signature, size_t *slen, const u_char *data, size_t dlen, const char *alg, u_int compat) { return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat); } openssh-7.2p2/ssh_api.h010064400017500001750000000105241267006270000132530ustar00djmdjm/* $OpenBSD: ssh_api.h,v 1.1 2015/01/19 20:30:23 markus Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef API_H #define API_H #include #include #include "openbsd-compat/sys-queue.h" #include "cipher.h" #include "sshkey.h" #include "kex.h" #include "ssh.h" #include "ssh2.h" #include "packet.h" struct kex_params { char *proposal[PROPOSAL_MAX]; }; /* public SSH API functions */ /* * ssh_init() create a ssh connection object with given (optional) * key exchange parameters. */ int ssh_init(struct ssh **, int is_server, struct kex_params *kex_params); /* * release ssh connection state. */ void ssh_free(struct ssh *); /* * attach application specific data to the connection state */ void ssh_set_app_data(struct ssh *, void *); void *ssh_get_app_data(struct ssh *); /* * ssh_add_hostkey() registers a private/public hostkey for an ssh * connection. * ssh_add_hostkey() needs to be called before a key exchange is * initiated with ssh_packet_next(). * private hostkeys are required if we need to act as a server. * public hostkeys are used to verify the servers hostkey. */ int ssh_add_hostkey(struct ssh *ssh, struct sshkey *key); /* * ssh_set_verify_host_key_callback() registers a callback function * which should be called instead of the default verification. The * function given must return 0 if the hostkey is ok, -1 if the * verification has failed. */ int ssh_set_verify_host_key_callback(struct ssh *ssh, int (*cb)(struct sshkey *, struct ssh *)); /* * ssh_packet_next() advances to the next input packet and returns * the packet type in typep. * ssh_packet_next() works by processing an input byte-stream, * decrypting the received data and hiding the key-exchange from * the caller. * ssh_packet_next() sets typep if there is no new packet available. * in this case the caller must fill the input byte-stream by passing * the data received over network to ssh_input_append(). * additinally, the caller needs to send the resulting output * byte-stream back over the network. otherwise the key exchange * would not proceed. the output byte-stream is accessed through * ssh_output_ptr(). */ int ssh_packet_next(struct ssh *ssh, u_char *typep); /* * ssh_packet_payload() returns a pointer to the raw payload data of * the current input packet and the length of this payload. * the payload is accessible until ssh_packet_next() is called again. */ const u_char *ssh_packet_payload(struct ssh *ssh, size_t *lenp); /* * ssh_packet_put() creates an encrypted packet with the given type * and payload. * the encrypted packet is appended to the output byte-stream. */ int ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len); /* * ssh_input_space() checks if 'len' bytes can be appended to the * input byte-stream. */ int ssh_input_space(struct ssh *ssh, size_t len); /* * ssh_input_append() appends data to the input byte-stream. */ int ssh_input_append(struct ssh *ssh, const u_char *data, size_t len); /* * ssh_output_space() checks if 'len' bytes can be appended to the * output byte-stream. XXX */ int ssh_output_space(struct ssh *ssh, size_t len); /* * ssh_output_ptr() retrieves both a pointer and the length of the * current output byte-stream. the bytes need to be sent over the * network. the number of bytes that have been successfully sent can * be removed from the output byte-stream with ssh_output_consume(). */ const u_char *ssh_output_ptr(struct ssh *ssh, size_t *len); /* * ssh_output_consume() removes the given number of bytes from * the output byte-stream. */ int ssh_output_consume(struct ssh *ssh, size_t len); #endif openssh-7.2p2/ssh_config010064400017500001750000000031521267006270000135200ustar00djmdjm# $OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for # users, and the values can be changed in per-user configuration files # or on the command line. # Configuration data is parsed as follows: # 1. command line options # 2. user-specific file # 3. system-wide file # Any configuration value is only changed the first time it is set. # Thus, host-specific definitions should be at the beginning of the # configuration file, and defaults at the end. # Site-wide defaults for some commonly used options. For a comprehensive # list of available options, their meanings and defaults, please see the # ssh_config(5) man page. # Host * # ForwardAgent no # ForwardX11 no # RhostsRSAAuthentication no # RSAAuthentication yes # PasswordAuthentication yes # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no # BatchMode no # CheckHostIP yes # AddressFamily any # ConnectTimeout 0 # StrictHostKeyChecking ask # IdentityFile ~/.ssh/identity # IdentityFile ~/.ssh/id_rsa # IdentityFile ~/.ssh/id_dsa # IdentityFile ~/.ssh/id_ecdsa # IdentityFile ~/.ssh/id_ed25519 # Port 22 # Protocol 2 # Cipher 3des # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 # EscapeChar ~ # Tunnel no # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h openssh-7.2p2/ssh_config.5010064400017500001750000001417701267006270000136740ustar00djmdjm.\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $OpenBSD: ssh_config.5,v 1.228 2016/02/20 23:01:46 sobrado Exp $ .Dd $Mdocdate: February 20 2016 $ .Dt SSH_CONFIG 5 .Os .Sh NAME .Nm ssh_config .Nd OpenSSH SSH client configuration files .Sh SYNOPSIS .Nm ~/.ssh/config .Nm /etc/ssh/ssh_config .Sh DESCRIPTION .Xr ssh 1 obtains configuration data from the following sources in the following order: .Pp .Bl -enum -offset indent -compact .It command-line options .It user's configuration file .Pq Pa ~/.ssh/config .It system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El .Pp For each parameter, the first obtained value will be used. The configuration files contain sections separated by .Dq Host specifications, and that section is only applied for hosts that match one of the patterns given in the specification. The matched host name is usually the one given on the command line (see the .Cm CanonicalizeHostname option for exceptions.) .Pp Since the first obtained value for each parameter is used, more host-specific declarations should be given near the beginning of the file, and general defaults at the end. .Pp The configuration file has the following format: .Pp Empty lines and lines starting with .Ql # are comments. Otherwise a line is of the format .Dq keyword arguments . Configuration options may be separated by whitespace or optional whitespace and exactly one .Ql = ; the latter format is useful to avoid the need to quote whitespace when specifying configuration options using the .Nm ssh , .Nm scp , and .Nm sftp .Fl o option. Arguments may optionally be enclosed in double quotes .Pq \&" in order to represent arguments containing spaces. .Pp The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): .Bl -tag -width Ds .It Cm Host Restricts the following declarations (up to the next .Cm Host or .Cm Match keyword) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is provided, they should be separated by whitespace. A single .Ql * as a pattern can be used to provide global defaults for all hosts. The host is usually the .Ar hostname argument given on the command line (see the .Cm CanonicalizeHostname option for exceptions.) .Pp A pattern entry may be negated by prefixing it with an exclamation mark .Pq Sq !\& . If a negated entry is matched, then the .Cm Host entry is ignored, regardless of whether any other patterns on the line match. Negated matches are therefore useful to provide exceptions for wildcard matches. .Pp See .Sx PATTERNS for more information on patterns. .It Cm Match Restricts the following declarations (up to the next .Cm Host or .Cm Match keyword) to be used only when the conditions following the .Cm Match keyword are satisfied. Match conditions are specified using one or more criteria or the single token .Cm all which always matches. The available criteria keywords are: .Cm canonical , .Cm exec , .Cm host , .Cm originalhost , .Cm user , and .Cm localuser . The .Cm all criteria must appear alone or immediately after .Cm canonical . Other criteria may be combined arbitrarily. All criteria but .Cm all and .Cm canonical require an argument. Criteria may be negated by prepending an exclamation mark .Pq Sq !\& . .Pp The .Cm canonical keyword matches only when the configuration file is being re-parsed after hostname canonicalization (see the .Cm CanonicalizeHostname option.) This may be useful to specify conditions that work with canonical host names only. The .Cm exec keyword executes the specified command under the user's shell. If the command returns a zero exit status then the condition is considered true. Commands containing whitespace characters must be quoted. The following character sequences in the command will be expanded prior to execution: .Ql %L will be substituted by the first component of the local host name, .Ql %l will be substituted by the local host name (including any domain name), .Ql %h will be substituted by the target host name, .Ql %n will be substituted by the original target host name specified on the command-line, .Ql %p the destination port, .Ql %r by the remote login username, and .Ql %u by the username of the user running .Xr ssh 1 . .Pp The other keywords' criteria must be single entries or comma-separated lists and may use the wildcard and negation operators described in the .Sx PATTERNS section. The criteria for the .Cm host keyword are matched against the target hostname, after any substitution by the .Cm Hostname or .Cm CanonicalizeHostname options. The .Cm originalhost keyword matches against the hostname as it was specified on the command-line. The .Cm user keyword matches against the target username on the remote host. The .Cm localuser keyword matches against the name of the local user running .Xr ssh 1 (this keyword may be useful in system-wide .Nm files). .It Cm AddKeysToAgent Specifies whether keys should be automatically added to a running .Xr ssh-agent 1 . If this option is set to .Dq yes and a key is loaded from a file, the key and its passphrase are added to the agent with the default lifetime, as if by .Xr ssh-add 1 . If this option is set to .Dq ask , .Nm ssh will require confirmation using the .Ev SSH_ASKPASS program before adding a key (see .Xr ssh-add 1 for details). If this option is set to .Dq confirm , each use of the key must be confirmed, as if the .Fl c option was specified to .Xr ssh-add 1 . If this option is set to .Dq no , no keys are added to the agent. The argument must be .Dq yes , .Dq confirm , .Dq ask , or .Dq no . The default is .Dq no . .It Cm AddressFamily Specifies which address family to use when connecting. Valid arguments are .Dq any , .Dq inet (use IPv4 only), or .Dq inet6 (use IPv6 only). The default is .Dq any . .It Cm BatchMode If set to .Dq yes , passphrase/password querying will be disabled. This option is useful in scripts and other batch jobs where no user is present to supply the password. The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm BindAddress Use the specified address on the local machine as the source address of the connection. Only useful on systems with more than one address. Note that this option does not work if .Cm UsePrivilegedPort is set to .Dq yes . .It Cm CanonicalDomains When .Cm CanonicalizeHostname is enabled, this option specifies the list of domain suffixes in which to search for the specified destination host. .It Cm CanonicalizeFallbackLocal Specifies whether to fail with an error when hostname canonicalization fails. The default, .Dq yes , will attempt to look up the unqualified hostname using the system resolver's search rules. A value of .Dq no will cause .Xr ssh 1 to fail instantly if .Cm CanonicalizeHostname is enabled and the target hostname cannot be found in any of the domains specified by .Cm CanonicalDomains . .It Cm CanonicalizeHostname Controls whether explicit hostname canonicalization is performed. The default, .Dq no , is not to perform any name rewriting and let the system resolver handle all hostname lookups. If set to .Dq yes then, for connections that do not use a .Cm ProxyCommand , .Xr ssh 1 will attempt to canonicalize the hostname specified on the command line using the .Cm CanonicalDomains suffixes and .Cm CanonicalizePermittedCNAMEs rules. If .Cm CanonicalizeHostname is set to .Dq always , then canonicalization is applied to proxied connections too. .Pp If this option is enabled, then the configuration files are processed again using the new target name to pick up any new configuration in matching .Cm Host and .Cm Match stanzas. .It Cm CanonicalizeMaxDots Specifies the maximum number of dot characters in a hostname before canonicalization is disabled. The default, .Dq 1 , allows a single dot (i.e. hostname.subdomain). .It Cm CanonicalizePermittedCNAMEs Specifies rules to determine whether CNAMEs should be followed when canonicalizing hostnames. The rules consist of one or more arguments of .Ar source_domain_list : Ns Ar target_domain_list , where .Ar source_domain_list is a pattern-list of domains that may follow CNAMEs in canonicalization, and .Ar target_domain_list is a pattern-list of domains that they may resolve to. .Pp For example, .Dq *.a.example.com:*.b.example.com,*.c.example.com will allow hostnames matching .Dq *.a.example.com to be canonicalized to names in the .Dq *.b.example.com or .Dq *.c.example.com domains. .It Cm CertificateFile Specifies a file from which the user's certificate is read. A corresponding private key must be provided separately in order to use this certificate either from an .Cm IdentityFile directive or .Fl i flag to .Xr ssh 1 , via .Xr ssh-agent 1 , or via a .Cm PKCS11Provider . .Pp The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: .Ql %d (local user's home directory), .Ql %u (local user name), .Ql %l (local host name), .Ql %h (remote host name) or .Ql %r (remote user name). .Pp It is possible to have multiple certificate files specified in configuration files; these certificates will be tried in sequence. Multiple .Cm CertificateFile directives will add to the list of certificates used for authentication. .It Cm ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be .Dq yes or .Dq no . The default is .Dq yes . .It Cm CheckHostIP If this flag is set to .Dq yes , .Xr ssh 1 will additionally check the host IP address in the .Pa known_hosts file. This allows ssh to detect if a host key changed due to DNS spoofing and will add addresses of destination hosts to .Pa ~/.ssh/known_hosts in the process, regardless of the setting of .Cm StrictHostKeyChecking . If the option is set to .Dq no , the check will not be executed. The default is .Dq yes . .It Cm Cipher Specifies the cipher to use for encrypting the session in protocol version 1. Currently, .Dq blowfish , .Dq 3des , and .Dq des are supported. .Ar des is only supported in the .Xr ssh 1 client for interoperability with legacy protocol 1 implementations that do not support the .Ar 3des cipher. Its use is strongly discouraged due to cryptographic weaknesses. The default is .Dq 3des . .It Cm Ciphers Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. If the specified value begins with a .Sq + character, then the specified ciphers will be appended to the default set instead of replacing them. .Pp The supported ciphers are: .Pp .Bl -item -compact -offset indent .It 3des-cbc .It aes128-cbc .It aes192-cbc .It aes256-cbc .It aes128-ctr .It aes192-ctr .It aes256-ctr .It aes128-gcm@openssh.com .It aes256-gcm@openssh.com .It arcfour .It arcfour128 .It arcfour256 .It blowfish-cbc .It cast128-cbc .It chacha20-poly1305@openssh.com .El .Pp The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com, aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc .Ed .Pp The list of available ciphers may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq cipher . .It Cm ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be cleared. This option is primarily useful when used from the .Xr ssh 1 command line to clear port forwardings set in configuration files, and is automatically set by .Xr scp 1 and .Xr sftp 1 . The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm Compression Specifies whether to use compression. The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm CompressionLevel Specifies the compression level to use if compression is enabled. The argument must be an integer from 1 (fast) to 9 (slow, best). The default level is 6, which is good for most applications. The meaning of the values is the same as in .Xr gzip 1 . Note that this option applies to protocol version 1 only. .It Cm ConnectionAttempts Specifies the number of tries (one per second) to make before exiting. The argument must be an integer. This may be useful in scripts if the connection sometimes fails. The default is 1. .It Cm ConnectTimeout Specifies the timeout (in seconds) used when connecting to the SSH server, instead of using the default system TCP timeout. This value is used only when the target is down or really unreachable, not when it refuses the connection. .It Cm ControlMaster Enables the sharing of multiple sessions over a single network connection. When set to .Dq yes , .Xr ssh 1 will listen for connections on a control socket specified using the .Cm ControlPath argument. Additional sessions can connect to this socket using the same .Cm ControlPath with .Cm ControlMaster set to .Dq no (the default). These sessions will try to reuse the master instance's network connection rather than initiating new ones, but will fall back to connecting normally if the control socket does not exist, or is not listening. .Pp Setting this to .Dq ask will cause ssh to listen for control connections, but require confirmation using .Xr ssh-askpass 1 . If the .Cm ControlPath cannot be opened, ssh will continue without connecting to a master instance. .Pp X11 and .Xr ssh-agent 1 forwarding is supported over these multiplexed connections, however the display and agent forwarded will be the one belonging to the master connection i.e. it is not possible to forward multiple displays or agents. .Pp Two additional options allow for opportunistic multiplexing: try to use a master connection but fall back to creating a new one if one does not already exist. These options are: .Dq auto and .Dq autoask . The latter requires confirmation like the .Dq ask option. .It Cm ControlPath Specify the path to the control socket used for connection sharing as described in the .Cm ControlMaster section above or the string .Dq none to disable connection sharing. In the path, .Ql %L will be substituted by the first component of the local host name, .Ql %l will be substituted by the local host name (including any domain name), .Ql %h will be substituted by the target host name, .Ql %n will be substituted by the original target host name specified on the command line, .Ql %p the destination port, .Ql %r by the remote login username, .Ql %u by the username and .Ql %i by the numeric user ID (uid) of the user running .Xr ssh 1 , and .Ql \&%C by a hash of the concatenation: %l%h%p%r. It is recommended that any .Cm ControlPath used for opportunistic connection sharing include at least %h, %p, and %r (or alternatively %C) and be placed in a directory that is not writable by other users. This ensures that shared connections are uniquely identified. .It Cm ControlPersist When used in conjunction with .Cm ControlMaster , specifies that the master connection should remain open in the background (waiting for future client connections) after the initial client connection has been closed. If set to .Dq no , then the master connection will not be placed into the background, and will close as soon as the initial client connection is closed. If set to .Dq yes or .Dq 0 , then the master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the .Xr ssh 1 .Dq Fl O No exit option). If set to a time in seconds, or a time in any of the formats documented in .Xr sshd_config 5 , then the backgrounded master connection will automatically terminate after it has remained idle (with no client connections) for the specified time. .It Cm DynamicForward Specifies that a TCP port on the local machine be forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. .Pp The argument must be .Sm off .Oo Ar bind_address : Oc Ar port . .Sm on IPv6 addresses can be specified by enclosing addresses in square brackets. By default, the local port is bound in accordance with the .Cm GatewayPorts setting. However, an explicit .Ar bind_address may be used to bind the connection to a specific address. The .Ar bind_address of .Dq localhost indicates that the listening port be bound for local use only, while an empty address or .Sq * indicates that the port should be available from all interfaces. .Pp Currently the SOCKS4 and SOCKS5 protocols are supported, and .Xr ssh 1 will act as a SOCKS server. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. .It Cm EnableSSHKeysign Setting this option to .Dq yes in the global client configuration file .Pa /etc/ssh/ssh_config enables the use of the helper program .Xr ssh-keysign 8 during .Cm HostbasedAuthentication . The argument must be .Dq yes or .Dq no . The default is .Dq no . This option should be placed in the non-hostspecific section. See .Xr ssh-keysign 8 for more information. .It Cm EscapeChar Sets the escape character (default: .Ql ~ ) . The escape character can also be set on the command line. The argument should be a single character, .Ql ^ followed by a letter, or .Dq none to disable the escape character entirely (making the connection transparent for binary data). .It Cm ExitOnForwardFailure Specifies whether .Xr ssh 1 should terminate the connection if it cannot set up all requested dynamic, tunnel, local, and remote port forwardings, (e.g.\& if either end is unable to bind and listen on a specified port). Note that .Cm ExitOnForwardFailure does not apply to connections made over port forwardings and will not, for example, cause .Xr ssh 1 to exit if TCP connections to the ultimate forwarding destination fail. The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: .Dq md5 and .Dq sha256 . The default is .Dq sha256 . .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. The argument must be .Dq yes or .Dq no . The default is .Dq no . .Pp Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's Unix-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. .It Cm ForwardX11 Specifies whether X11 connections will be automatically redirected over the secure channel and .Ev DISPLAY set. The argument must be .Dq yes or .Dq no . The default is .Dq no . .Pp X11 forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the user's X11 authorization database) can access the local X11 display through the forwarded connection. An attacker may then be able to perform activities such as keystroke monitoring if the .Cm ForwardX11Trusted option is also enabled. .It Cm ForwardX11Timeout Specify a timeout for untrusted X11 forwarding using the format described in the TIME FORMATS section of .Xr sshd_config 5 . X11 connections received by .Xr ssh 1 after this time will be refused. The default is to disable untrusted X11 forwarding after twenty minutes has elapsed. .It Cm ForwardX11Trusted If this option is set to .Dq yes , remote X11 clients will have full access to the original X11 display. .Pp If this option is set to .Dq no , remote X11 clients will be considered untrusted and prevented from stealing or tampering with data belonging to trusted X11 clients. Furthermore, the .Xr xauth 1 token used for the session will be set to expire after 20 minutes. Remote clients will be refused access after this time. .Pp The default is .Dq no . .Pp See the X11 SECURITY extension specification for full details on the restrictions imposed on untrusted clients. .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to local forwarded ports. By default, .Xr ssh 1 binds local port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. .Cm GatewayPorts can be used to specify that ssh should bind local port forwardings to the wildcard address, thus allowing remote hosts to connect to forwarded ports. The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm GlobalKnownHostsFile Specifies one or more files to use for the global host key database, separated by whitespace. The default is .Pa /etc/ssh/ssh_known_hosts , .Pa /etc/ssh/ssh_known_hosts2 . .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is .Dq no . .It Cm HashKnownHosts Indicates that .Xr ssh 1 should hash host names and addresses when they are added to .Pa ~/.ssh/known_hosts . These hashed names may be used normally by .Xr ssh 1 and .Xr sshd 8 , but they do not reveal identifying information should the file's contents be disclosed. The default is .Dq no . Note that existing names and addresses in known hosts files will not be converted automatically, but may be manually hashed using .Xr ssh-keygen 1 . .It Cm HostbasedAuthentication Specifies whether to try rhosts based authentication with public key authentication. The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm HostbasedKeyTypes Specifies the key types that will be used for hostbased authentication as a comma-separated pattern list. Alternately if the specified value begins with a .Sq + character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp The .Fl Q option of .Xr ssh 1 may be used to list supported key types. .It Cm HostKeyAlgorithms Specifies the host key algorithms that the client wants to use in order of preference. Alternately if the specified value begins with a .Sq + character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp If hostkeys are known for the destination host then this default is modified to prefer their algorithms. .Pp The list of available key types may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq key . .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key in the host key database files. This option is useful for tunneling SSH connections or for multiple servers running on a single host. .It Cm HostName Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts. If the hostname contains the character sequence .Ql %h , then this will be replaced with the host name specified on the command line (this is useful for manipulating unqualified names). The character sequence .Ql %% will be replaced by a single .Ql % character, which may be used when specifying IPv6 link-local addresses. .Pp The default is the name given on the command line. Numeric IP addresses are also permitted (both on the command line and in .Cm HostName specifications). .It Cm IdentitiesOnly Specifies that .Xr ssh 1 should only use the authentication identity and certificate files explicitly configured in the .Nm files or passed on the .Xr ssh 1 command-line, even if .Xr ssh-agent 1 or a .Cm PKCS11Provider offers more identities. The argument to this keyword must be .Dq yes or .Dq no . This option is intended for situations where ssh-agent offers many different identities. The default is .Dq no . .It Cm IdentityFile Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication identity is read. The default is .Pa ~/.ssh/identity for protocol version 1, and .Pa ~/.ssh/id_dsa , .Pa ~/.ssh/id_ecdsa , .Pa ~/.ssh/id_ed25519 and .Pa ~/.ssh/id_rsa for protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication unless .Cm IdentitiesOnly is set. If no certificates have been explicitly specified by .Cm CertificateFile , .Xr ssh 1 will try to load certificate information from the filename obtained by appending .Pa -cert.pub to the path of a specified .Cm IdentityFile . .Pp The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: .Ql %d (local user's home directory), .Ql %u (local user name), .Ql %l (local host name), .Ql %h (remote host name) or .Ql %r (remote user name). .Pp It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence. Multiple .Cm IdentityFile directives will add to the list of identities tried (this behaviour differs from that of other configuration directives). .Pp .Cm IdentityFile may be used in conjunction with .Cm IdentitiesOnly to select which identities in an agent are offered during authentication. .Cm IdentityFile may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. This may be used to suppress errors if .Nm contains options that are unrecognised by .Xr ssh 1 . It is recommended that .Cm IgnoreUnknown be listed early in the configuration file as it will not be applied to unknown options that appear before it. .It Cm IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. Accepted values are .Dq af11 , .Dq af12 , .Dq af13 , .Dq af21 , .Dq af22 , .Dq af23 , .Dq af31 , .Dq af32 , .Dq af33 , .Dq af41 , .Dq af42 , .Dq af43 , .Dq cs0 , .Dq cs1 , .Dq cs2 , .Dq cs3 , .Dq cs4 , .Dq cs5 , .Dq cs6 , .Dq cs7 , .Dq ef , .Dq lowdelay , .Dq throughput , .Dq reliability , or a numeric value. This option may take one or two arguments, separated by whitespace. If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is .Dq lowdelay for interactive sessions and .Dq throughput for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be .Dq yes or .Dq no . The default is .Dq yes . .It Cm KbdInteractiveDevices Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. The default is to use the server specified list. The methods available vary depending on what the server supports. For an OpenSSH server, it may be zero or more of: .Dq bsdauth , .Dq pam , and .Dq skey . .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. Alternately if the specified value begins with a .Sq + character, then the specified methods will be appended to the default set instead of replacing them. The default is: .Bd -literal -offset indent curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1 .Ed .Pp The list of available key exchange algorithms may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq kex . .It Cm LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. The command string extends to the end of the line, and is executed with the user's shell. The following escape character substitutions will be performed: .Ql %d (local user's home directory), .Ql %h (remote host name), .Ql %l (local host name), .Ql %n (host name as provided on the command line), .Ql %p (remote port), .Ql %r (remote user name) or .Ql %u (local user name) or .Ql \&%C by a hash of the concatenation: %l%h%p%r. .Pp The command is run synchronously and does not have access to the session of the .Xr ssh 1 that spawned it. It should not be used for interactive commands. .Pp This directive is ignored unless .Cm PermitLocalCommand has been enabled. .It Cm LocalForward Specifies that a TCP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. The first argument must be .Sm off .Oo Ar bind_address : Oc Ar port .Sm on and the second argument must be .Ar host : Ns Ar hostport . IPv6 addresses can be specified by enclosing addresses in square brackets. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the .Cm GatewayPorts setting. However, an explicit .Ar bind_address may be used to bind the connection to a specific address. The .Ar bind_address of .Dq localhost indicates that the listening port be bound for local use only, while an empty address or .Sq * indicates that the port should be available from all interfaces. .It Cm LogLevel Gives the verbosity level that is used when logging messages from .Xr ssh 1 . The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of verbose output. .It Cm MACs Specifies the MAC (message authentication code) algorithms in order of preference. The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated. If the specified value begins with a .Sq + character, then the specified algorithms will be appended to the default set instead of replacing them. .Pp The algorithms that contain .Dq -etm calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. .Pp The default is: .Bd -literal -offset indent umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512,hmac-sha1 .Ed .Pp The list of available MAC algorithms may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq mac . .It Cm NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of the machines and the user will get many warnings about changed host keys. However, this option disables host authentication for localhost. The argument to this keyword must be .Dq yes or .Dq no . The default is to check the host key for localhost. .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. The default is 3. .It Cm PasswordAuthentication Specifies whether to use password authentication. The argument to this keyword must be .Dq yes or .Dq no . The default is .Dq yes . .It Cm PermitLocalCommand Allow local command execution via the .Ic LocalCommand option or using the .Ic !\& Ns Ar command escape sequence in .Xr ssh 1 . The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm PKCS11Provider Specifies which PKCS#11 provider to use. The argument to this keyword is the PKCS#11 shared library .Xr ssh 1 should use to communicate with a PKCS#11 token providing the user's private RSA key. .It Cm Port Specifies the port number to connect on the remote host. The default is 22. .It Cm PreferredAuthentications Specifies the order in which the client should try authentication methods. This allows a client to prefer one method (e.g.\& .Cm keyboard-interactive ) over another method (e.g.\& .Cm password ) . The default is: .Bd -literal -offset indent gssapi-with-mic,hostbased,publickey, keyboard-interactive,password .Ed .It Cm Protocol Specifies the protocol versions .Xr ssh 1 should support in order of preference. The possible values are .Sq 1 and .Sq 2 . Multiple versions must be comma-separated. When this option is set to .Dq 2,1 .Nm ssh will try version 2 and fall back to version 1 if version 2 is not available. The default is .Sq 2 . Protocol 1 suffers from a number of cryptographic weaknesses and should not be used. It is only offered to support legacy devices. .It Cm ProxyCommand Specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed using the user's shell .Ql exec directive to avoid a lingering shell process. .Pp In the command string, any occurrence of .Ql %h will be substituted by the host name to connect, .Ql %p by the port, and .Ql %r by the remote user name. The command can be basically anything, and should read from its standard input and write to its standard output. It should eventually connect an .Xr sshd 8 server running on some machine, or execute .Ic sshd -i somewhere. Host key management will be done using the HostName of the host being connected (defaulting to the name typed by the user). Setting the command to .Dq none disables this option entirely. Note that .Cm CheckHostIP is not available for connects with a proxy command. .Pp This directive is useful in conjunction with .Xr nc 1 and its proxy support. For example, the following directive would connect via an HTTP proxy at 192.0.2.0: .Bd -literal -offset 3n ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p .Ed .It Cm ProxyUseFdpass Specifies that .Cm ProxyCommand will pass a connected file descriptor back to .Xr ssh 1 instead of continuing to execute and pass data. The default is .Dq no . .It Cm PubkeyAcceptedKeyTypes Specifies the key types that will be used for public key authentication as a comma-separated pattern list. Alternately if the specified value begins with a .Sq + character, then the key types after it will be appended to the default instead of replacing it. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp The .Fl Q option of .Xr ssh 1 may be used to list supported key types. .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be .Dq yes or .Dq no . The default is .Dq yes . .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may have a suffix of .Sq K , .Sq M , or .Sq G to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between .Sq 1G and .Sq 4G , depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the TIME FORMATS section of .Xr sshd_config 5 . The default value for .Cm RekeyLimit is .Dq default none , which means that rekeying is performed after the cipher's default amount of data has been sent or received and no time based rekeying is done. .It Cm RemoteForward Specifies that a TCP port on the remote machine be forwarded over the secure channel to the specified host and port from the local machine. The first argument must be .Sm off .Oo Ar bind_address : Oc Ar port .Sm on and the second argument must be .Ar host : Ns Ar hostport . IPv6 addresses can be specified by enclosing addresses in square brackets. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Privileged ports can be forwarded only when logging in as root on the remote machine. .Pp If the .Ar port argument is .Ql 0 , the listen port will be dynamically allocated on the server and reported to the client at run time. .Pp If the .Ar bind_address is not specified, the default is to only bind to loopback addresses. If the .Ar bind_address is .Ql * or an empty string, then the forwarding is requested to listen on all interfaces. Specifying a remote .Ar bind_address will only succeed if the server's .Cm GatewayPorts option is enabled (see .Xr sshd_config 5 ) . .It Cm RequestTTY Specifies whether to request a pseudo-tty for the session. The argument may be one of: .Dq no (never request a TTY), .Dq yes (always request a TTY when standard input is a TTY), .Dq force (always request a TTY) or .Dq auto (request a TTY when opening a login session). This option mirrors the .Fl t and .Fl T flags for .Xr ssh 1 . .It Cm RevokedHostKeys Specifies revoked host public keys. Keys listed in this file will be refused for host authentication. Note that if this file does not exist or is not readable, then host authentication will be refused for all hosts. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by .Xr ssh-keygen 1 . For more information on KRLs, see the KEY REVOCATION LISTS section in .Xr ssh-keygen 1 . .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. The argument must be .Dq yes or .Dq no . The default is .Dq no . This option applies to protocol version 1 only and requires .Xr ssh 1 to be setuid root. .It Cm RSAAuthentication Specifies whether to try RSA authentication. The argument to this keyword must be .Dq yes or .Dq no . RSA authentication will only be attempted if the identity file exists, or an authentication agent is running. The default is .Dq yes . Note that this option applies to protocol version 1 only. .It Cm SendEnv Specifies what variables from the local .Xr environ 7 should be sent to the server. The server must also support it, and the server must be configured to accept these environment variables. Note that the .Ev TERM environment variable is always sent whenever a pseudo-terminal is requested as it is required by the protocol. Refer to .Cm AcceptEnv in .Xr sshd_config 5 for how to configure the server. Variables are specified by name, which may contain wildcard characters. Multiple environment variables may be separated by whitespace or spread across multiple .Cm SendEnv directives. The default is not to send any environment variables. .Pp See .Sx PATTERNS for more information on patterns. .It Cm ServerAliveCountMax Sets the number of server alive messages (see below) which may be sent without .Xr ssh 1 receiving any messages back from the server. If this threshold is reached while server alive messages are being sent, ssh will disconnect from the server, terminating the session. It is important to note that the use of server alive messages is very different from .Cm TCPKeepAlive (below). The server alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by .Cm TCPKeepAlive is spoofable. The server alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive. .Pp The default value is 3. If, for example, .Cm ServerAliveInterval (see below) is set to 15 and .Cm ServerAliveCountMax is left at the default, if the server becomes unresponsive, ssh will disconnect after approximately 45 seconds. .It Cm ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, .Xr ssh 1 will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. .It Cm StreamLocalBindMask Sets the octal file creation mode mask .Pq umask used when creating a Unix-domain socket file for local or remote port forwarding. This option is only used for port forwarding to a Unix-domain socket file. .Pp The default value is 0177, which creates a Unix-domain socket file that is readable and writable only by the owner. Note that not all operating systems honor the file mode on Unix-domain socket files. .It Cm StreamLocalBindUnlink Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new one. If the socket file already exists and .Cm StreamLocalBindUnlink is not enabled, .Nm ssh will be unable to forward the port to the Unix-domain socket file. This option is only used for port forwarding to a Unix-domain socket file. .Pp The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm StrictHostKeyChecking If this flag is set to .Dq yes , .Xr ssh 1 will never automatically add host keys to the .Pa ~/.ssh/known_hosts file, and refuses to connect to hosts whose host key has changed. This provides maximum protection against trojan horse attacks, though it can be annoying when the .Pa /etc/ssh/ssh_known_hosts file is poorly maintained or when connections to new hosts are frequently made. This option forces the user to manually add all new hosts. If this flag is set to .Dq no , ssh will automatically add new host keys to the user known hosts files. If this flag is set to .Dq ask , new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and ssh will refuse to connect to hosts whose host key has changed. The host keys of known hosts will be verified automatically in all cases. The argument must be .Dq yes , .Dq no , or .Dq ask . The default is .Dq ask . .It Cm TCPKeepAlive Specifies whether the system should send TCP keepalive messages to the other side. If they are sent, death of the connection or crash of one of the machines will be properly noticed. However, this means that connections will die if the route is down temporarily, and some people find it annoying. .Pp The default is .Dq yes (to send TCP keepalive messages), and the client will notice if the network goes down or the remote host dies. This is important in scripts, and many users want it too. .Pp To disable TCP keepalive messages, the value should be set to .Dq no . .It Cm Tunnel Request .Xr tun 4 device forwarding between the client and the server. The argument must be .Dq yes , .Dq point-to-point (layer 3), .Dq ethernet (layer 2), or .Dq no . Specifying .Dq yes requests the default tunnel mode, which is .Dq point-to-point . The default is .Dq no . .It Cm TunnelDevice Specifies the .Xr tun 4 devices to open on the client .Pq Ar local_tun and the server .Pq Ar remote_tun . .Pp The argument must be .Sm off .Ar local_tun Op : Ar remote_tun . .Sm on The devices may be specified by numerical ID or the keyword .Dq any , which uses the next available tunnel device. If .Ar remote_tun is not specified, it defaults to .Dq any . The default is .Dq any:any . .It Cm UpdateHostKeys Specifies whether .Xr ssh 1 should accept notifications of additional hostkeys from the server sent after authentication has completed and add them to .Cm UserKnownHostsFile . The argument must be .Dq yes , .Dq no (the default) or .Dq ask . Enabling this option allows learning alternate hostkeys for a server and supports graceful key rotation by allowing a server to send replacement public keys before old ones are removed. Additional hostkeys are only accepted if the key used to authenticate the host was already trusted or explicitly accepted by the user. If .Cm UpdateHostKeys is set to .Dq ask , then the user is asked to confirm the modifications to the known_hosts file. Confirmation is currently incompatible with .Cm ControlPersist , and will be disabled if it is enabled. .Pp Presently, only .Xr sshd 8 from OpenSSH 6.8 and greater support the .Dq hostkeys@openssh.com protocol extension used to inform the client of all the server's hostkeys. .It Cm UsePrivilegedPort Specifies whether to use a privileged port for outgoing connections. The argument must be .Dq yes or .Dq no . The default is .Dq no . If set to .Dq yes , .Xr ssh 1 must be setuid root. Note that this option must be set to .Dq yes for .Cm RhostsRSAAuthentication with older servers. .It Cm User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line. .It Cm UserKnownHostsFile Specifies one or more files to use for the user host key database, separated by whitespace. The default is .Pa ~/.ssh/known_hosts , .Pa ~/.ssh/known_hosts2 . .It Cm VerifyHostKeyDNS Specifies whether to verify the remote key using DNS and SSHFP resource records. If this option is set to .Dq yes , the client will implicitly trust keys that match a secure fingerprint from DNS. Insecure fingerprints will be handled as if this option was set to .Dq ask . If this option is set to .Dq ask , information on fingerprint match will be displayed, but the user will still need to confirm new host keys according to the .Cm StrictHostKeyChecking option. The argument must be .Dq yes , .Dq no , or .Dq ask . The default is .Dq no . .Pp See also VERIFYING HOST KEYS in .Xr ssh 1 . .It Cm VisualHostKey If this flag is set to .Dq yes , an ASCII art representation of the remote host key fingerprint is printed in addition to the fingerprint string at login and for unknown host keys. If this flag is set to .Dq no , no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. The default is .Dq no . .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 program. The default is .Pa /usr/X11R6/bin/xauth . .El .Sh PATTERNS A .Em pattern consists of zero or more non-whitespace characters, .Sq * (a wildcard that matches zero or more characters), or .Sq ?\& (a wildcard that matches exactly one character). For example, to specify a set of declarations for any host in the .Dq .co.uk set of domains, the following pattern could be used: .Pp .Dl Host *.co.uk .Pp The following pattern would match any host in the 192.168.0.[0-9] network range: .Pp .Dl Host 192.168.0.? .Pp A .Em pattern-list is a comma-separated list of patterns. Patterns within pattern-lists may be negated by preceding them with an exclamation mark .Pq Sq !\& . For example, to allow a key to be used from anywhere within an organization except from the .Dq dialup pool, the following entry (in authorized_keys) could be used: .Pp .Dl from=\&"!*.dialup.example.com,*.example.com\&" .Sh FILES .Bl -tag -width Ds .It Pa ~/.ssh/config This is the per-user configuration file. The format of this file is described above. This file is used by the SSH client. Because of the potential for abuse, this file must have strict permissions: read/write for the user, and not accessible by others. .It Pa /etc/ssh/ssh_config Systemwide configuration file. This file provides defaults for those values that are not specified in the user's configuration file, and for those users who do not have a configuration file. This file must be world-readable. .El .Sh SEE ALSO .Xr ssh 1 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.2p2/sshbuf-getput-basic.c010064400017500001750000000223341267006270000155010ustar00djmdjm/* $OpenBSD: sshbuf-getput-basic.c,v 1.5 2015/10/20 23:24:25 mmcc Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ #define SSHBUF_INTERNAL #include "includes.h" #include #include #include #include #include "ssherr.h" #include "sshbuf.h" int sshbuf_get(struct sshbuf *buf, void *v, size_t len) { const u_char *p = sshbuf_ptr(buf); int r; if ((r = sshbuf_consume(buf, len)) < 0) return r; if (v != NULL && len != 0) memcpy(v, p, len); return 0; } int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; if ((r = sshbuf_consume(buf, 8)) < 0) return r; if (valp != NULL) *valp = PEEK_U64(p); return 0; } int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; if ((r = sshbuf_consume(buf, 4)) < 0) return r; if (valp != NULL) *valp = PEEK_U32(p); return 0; } int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; if ((r = sshbuf_consume(buf, 2)) < 0) return r; if (valp != NULL) *valp = PEEK_U16(p); return 0; } int sshbuf_get_u8(struct sshbuf *buf, u_char *valp) { const u_char *p = sshbuf_ptr(buf); int r; if ((r = sshbuf_consume(buf, 1)) < 0) return r; if (valp != NULL) *valp = (u_int8_t)*p; return 0; } int sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) { const u_char *val; size_t len; int r; if (valp != NULL) *valp = NULL; if (lenp != NULL) *lenp = 0; if ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0) return r; if (valp != NULL) { if ((*valp = malloc(len + 1)) == NULL) { SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); return SSH_ERR_ALLOC_FAIL; } if (len != 0) memcpy(*valp, val, len); (*valp)[len] = '\0'; } if (lenp != NULL) *lenp = len; return 0; } int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp) { size_t len; const u_char *p; int r; if (valp != NULL) *valp = NULL; if (lenp != NULL) *lenp = 0; if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0) return r; if (valp != NULL) *valp = p; if (lenp != NULL) *lenp = len; if (sshbuf_consume(buf, len + 4) != 0) { /* Shouldn't happen */ SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); SSHBUF_ABORT(); return SSH_ERR_INTERNAL_ERROR; } return 0; } int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, size_t *lenp) { u_int32_t len; const u_char *p = sshbuf_ptr(buf); if (valp != NULL) *valp = NULL; if (lenp != NULL) *lenp = 0; if (sshbuf_len(buf) < 4) { SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); return SSH_ERR_MESSAGE_INCOMPLETE; } len = PEEK_U32(p); if (len > SSHBUF_SIZE_MAX - 4) { SSHBUF_DBG(("SSH_ERR_STRING_TOO_LARGE")); return SSH_ERR_STRING_TOO_LARGE; } if (sshbuf_len(buf) - 4 < len) { SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); return SSH_ERR_MESSAGE_INCOMPLETE; } if (valp != NULL) *valp = p + 4; if (lenp != NULL) *lenp = len; return 0; } int sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp) { size_t len; const u_char *p, *z; int r; if (valp != NULL) *valp = NULL; if (lenp != NULL) *lenp = 0; if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) return r; /* Allow a \0 only at the end of the string */ if (len > 0 && (z = memchr(p , '\0', len)) != NULL && z < p + len - 1) { SSHBUF_DBG(("SSH_ERR_INVALID_FORMAT")); return SSH_ERR_INVALID_FORMAT; } if ((r = sshbuf_skip_string(buf)) != 0) return -1; if (valp != NULL) { if ((*valp = malloc(len + 1)) == NULL) { SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); return SSH_ERR_ALLOC_FAIL; } if (len != 0) memcpy(*valp, p, len); (*valp)[len] = '\0'; } if (lenp != NULL) *lenp = (size_t)len; return 0; } int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v) { u_int32_t len; u_char *p; int r; /* * Use sshbuf_peek_string_direct() to figure out if there is * a complete string in 'buf' and copy the string directly * into 'v'. */ if ((r = sshbuf_peek_string_direct(buf, NULL, NULL)) != 0 || (r = sshbuf_get_u32(buf, &len)) != 0 || (r = sshbuf_reserve(v, len, &p)) != 0 || (r = sshbuf_get(buf, p, len)) != 0) return r; return 0; } int sshbuf_put(struct sshbuf *buf, const void *v, size_t len) { u_char *p; int r; if ((r = sshbuf_reserve(buf, len, &p)) < 0) return r; if (len != 0) memcpy(p, v, len); return 0; } int sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v) { return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v)); } int sshbuf_putf(struct sshbuf *buf, const char *fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = sshbuf_putfv(buf, fmt, ap); va_end(ap); return r; } int sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap) { va_list ap2; int r, len; u_char *p; va_copy(ap2, ap); if ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if (len == 0) { r = 0; goto out; /* Nothing to do */ } va_end(ap2); va_copy(ap2, ap); if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0) goto out; if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) { r = SSH_ERR_INTERNAL_ERROR; goto out; /* Shouldn't happen */ } /* Consume terminating \0 */ if ((r = sshbuf_consume_end(buf, 1)) != 0) goto out; r = 0; out: va_end(ap2); return r; } int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val) { u_char *p; int r; if ((r = sshbuf_reserve(buf, 8, &p)) < 0) return r; POKE_U64(p, val); return 0; } int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val) { u_char *p; int r; if ((r = sshbuf_reserve(buf, 4, &p)) < 0) return r; POKE_U32(p, val); return 0; } int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val) { u_char *p; int r; if ((r = sshbuf_reserve(buf, 2, &p)) < 0) return r; POKE_U16(p, val); return 0; } int sshbuf_put_u8(struct sshbuf *buf, u_char val) { u_char *p; int r; if ((r = sshbuf_reserve(buf, 1, &p)) < 0) return r; p[0] = val; return 0; } int sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) { u_char *d; int r; if (len > SSHBUF_SIZE_MAX - 4) { SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); return SSH_ERR_NO_BUFFER_SPACE; } if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0) return r; POKE_U32(d, len); if (len != 0) memcpy(d + 4, v, len); return 0; } int sshbuf_put_cstring(struct sshbuf *buf, const char *v) { return sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v)); } int sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v) { return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v)); } int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp) { const u_char *p; size_t len; struct sshbuf *ret; int r; if (buf == NULL || bufp == NULL) return SSH_ERR_INVALID_ARGUMENT; *bufp = NULL; if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) return r; if ((ret = sshbuf_from(p, len)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_consume(buf, len + 4)) != 0 || /* Shouldn't happen */ (r = sshbuf_set_parent(ret, buf)) != 0) { sshbuf_free(ret); return r; } *bufp = ret; return 0; } int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len) { u_char *d; const u_char *s = (const u_char *)v; int r, prepend; if (len > SSHBUF_SIZE_MAX - 5) { SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); return SSH_ERR_NO_BUFFER_SPACE; } /* Skip leading zero bytes */ for (; len > 0 && *s == 0; len--, s++) ; /* * If most significant bit is set then prepend a zero byte to * avoid interpretation as a negative number. */ prepend = len > 0 && (s[0] & 0x80) != 0; if ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0) return r; POKE_U32(d, len + prepend); if (prepend) d[4] = 0; if (len != 0) memcpy(d + 4 + prepend, s, len); return 0; } int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp) { const u_char *d; size_t len, olen; int r; if ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0) return r; len = olen; /* Refuse negative (MSB set) bignums */ if ((len != 0 && (*d & 0x80) != 0)) return SSH_ERR_BIGNUM_IS_NEGATIVE; /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */ if (len > SSHBUF_MAX_BIGNUM + 1 || (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0)) return SSH_ERR_BIGNUM_TOO_LARGE; /* Trim leading zeros */ while (len > 0 && *d == 0x00) { d++; len--; } if (valp != NULL) *valp = d; if (lenp != NULL) *lenp = len; if (sshbuf_consume(buf, olen + 4) != 0) { /* Shouldn't happen */ SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); SSHBUF_ABORT(); return SSH_ERR_INTERNAL_ERROR; } return 0; } openssh-7.2p2/sshbuf-getput-crypto.c010064400017500001750000000132131267006270000157340ustar00djmdjm/* $OpenBSD: sshbuf-getput-crypto.c,v 1.5 2016/01/12 23:42:54 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ #define SSHBUF_INTERNAL #include "includes.h" #include #include #include #include #include #ifdef OPENSSL_HAS_ECC # include #endif /* OPENSSL_HAS_ECC */ #include "ssherr.h" #include "sshbuf.h" int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v) { const u_char *d; size_t len; int r; if ((r = sshbuf_get_bignum2_bytes_direct(buf, &d, &len)) != 0) return r; if (v != NULL && BN_bin2bn(d, len, v) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v) { const u_char *d = sshbuf_ptr(buf); u_int16_t len_bits; size_t len_bytes; /* Length in bits */ if (sshbuf_len(buf) < 2) return SSH_ERR_MESSAGE_INCOMPLETE; len_bits = PEEK_U16(d); len_bytes = (len_bits + 7) >> 3; if (len_bytes > SSHBUF_MAX_BIGNUM) return SSH_ERR_BIGNUM_TOO_LARGE; if (sshbuf_len(buf) < 2 + len_bytes) return SSH_ERR_MESSAGE_INCOMPLETE; if (v != NULL && BN_bin2bn(d + 2, len_bytes, v) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_consume(buf, 2 + len_bytes) != 0) { SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); SSHBUF_ABORT(); return SSH_ERR_INTERNAL_ERROR; } return 0; } #ifdef OPENSSL_HAS_ECC static int get_ec(const u_char *d, size_t len, EC_POINT *v, const EC_GROUP *g) { /* Refuse overlong bignums */ if (len == 0 || len > SSHBUF_MAX_ECPOINT) return SSH_ERR_ECPOINT_TOO_LARGE; /* Only handle uncompressed points */ if (*d != POINT_CONVERSION_UNCOMPRESSED) return SSH_ERR_INVALID_FORMAT; if (v != NULL && EC_POINT_oct2point(g, v, d, len, NULL) != 1) return SSH_ERR_INVALID_FORMAT; /* XXX assumption */ return 0; } int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g) { const u_char *d; size_t len; int r; if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0) return r; if ((r = get_ec(d, len, v, g)) != 0) return r; /* Skip string */ if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) { /* Shouldn't happen */ SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); SSHBUF_ABORT(); return SSH_ERR_INTERNAL_ERROR; } return 0; } int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v) { EC_POINT *pt = EC_POINT_new(EC_KEY_get0_group(v)); int r; const u_char *d; size_t len; if (pt == NULL) { SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); return SSH_ERR_ALLOC_FAIL; } if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0) { EC_POINT_free(pt); return r; } if ((r = get_ec(d, len, pt, EC_KEY_get0_group(v))) != 0) { EC_POINT_free(pt); return r; } if (EC_KEY_set_public_key(v, pt) != 1) { EC_POINT_free(pt); return SSH_ERR_ALLOC_FAIL; /* XXX assumption */ } EC_POINT_free(pt); /* Skip string */ if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) { /* Shouldn't happen */ SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); SSHBUF_ABORT(); return SSH_ERR_INTERNAL_ERROR; } return 0; } #endif /* OPENSSL_HAS_ECC */ int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v) { u_char d[SSHBUF_MAX_BIGNUM + 1]; int len = BN_num_bytes(v), prepend = 0, r; if (len < 0 || len > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; *d = '\0'; if (BN_bn2bin(v, d + 1) != len) return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */ /* If MSB is set, prepend a \0 */ if (len > 0 && (d[1] & 0x80) != 0) prepend = 1; if ((r = sshbuf_put_string(buf, d + 1 - prepend, len + prepend)) < 0) { explicit_bzero(d, sizeof(d)); return r; } explicit_bzero(d, sizeof(d)); return 0; } int sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v) { int r, len_bits = BN_num_bits(v); size_t len_bytes = (len_bits + 7) / 8; u_char d[SSHBUF_MAX_BIGNUM], *dp; if (len_bits < 0 || len_bytes > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; if (BN_bn2bin(v, d) != (int)len_bytes) return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */ if ((r = sshbuf_reserve(buf, len_bytes + 2, &dp)) < 0) { explicit_bzero(d, sizeof(d)); return r; } POKE_U16(dp, len_bits); if (len_bytes != 0) memcpy(dp + 2, d, len_bytes); explicit_bzero(d, sizeof(d)); return 0; } #ifdef OPENSSL_HAS_ECC int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g) { u_char d[SSHBUF_MAX_ECPOINT]; BN_CTX *bn_ctx; size_t len; int ret; if ((bn_ctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((len = EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx)) > SSHBUF_MAX_ECPOINT) { BN_CTX_free(bn_ctx); return SSH_ERR_INVALID_ARGUMENT; } if (EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED, d, len, bn_ctx) != len) { BN_CTX_free(bn_ctx); return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */ } BN_CTX_free(bn_ctx); ret = sshbuf_put_string(buf, d, len); explicit_bzero(d, len); return ret; } int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v) { return sshbuf_put_ec(buf, EC_KEY_get0_public_key(v), EC_KEY_get0_group(v)); } #endif /* OPENSSL_HAS_ECC */ openssh-7.2p2/sshbuf-misc.c010064400017500001750000000060771267006270000140530ustar00djmdjm/* $OpenBSD: sshbuf-misc.c,v 1.5 2015/10/05 17:11:21 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include "ssherr.h" #define SSHBUF_INTERNAL #include "sshbuf.h" void sshbuf_dump_data(const void *s, size_t len, FILE *f) { size_t i, j; const u_char *p = (const u_char *)s; for (i = 0; i < len; i += 16) { fprintf(f, "%.4zu: ", i); for (j = i; j < i + 16; j++) { if (j < len) fprintf(f, "%02x ", p[j]); else fprintf(f, " "); } fprintf(f, " "); for (j = i; j < i + 16; j++) { if (j < len) { if (isascii(p[j]) && isprint(p[j])) fprintf(f, "%c", p[j]); else fprintf(f, "."); } } fprintf(f, "\n"); } } void sshbuf_dump(struct sshbuf *buf, FILE *f) { fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf)); sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f); } char * sshbuf_dtob16(struct sshbuf *buf) { size_t i, j, len = sshbuf_len(buf); const u_char *p = sshbuf_ptr(buf); char *ret; const char hex[] = "0123456789abcdef"; if (len == 0) return strdup(""); if (SIZE_MAX / 2 <= len || (ret = malloc(len * 2 + 1)) == NULL) return NULL; for (i = j = 0; i < len; i++) { ret[j++] = hex[(p[i] >> 4) & 0xf]; ret[j++] = hex[p[i] & 0xf]; } ret[j] = '\0'; return ret; } char * sshbuf_dtob64(struct sshbuf *buf) { size_t len = sshbuf_len(buf), plen; const u_char *p = sshbuf_ptr(buf); char *ret; int r; if (len == 0) return strdup(""); plen = ((len + 2) / 3) * 4 + 1; if (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL) return NULL; if ((r = b64_ntop(p, len, ret, plen)) == -1) { explicit_bzero(ret, plen); free(ret); return NULL; } return ret; } int sshbuf_b64tod(struct sshbuf *buf, const char *b64) { size_t plen = strlen(b64); int nlen, r; u_char *p; if (plen == 0) return 0; if ((p = malloc(plen)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((nlen = b64_pton(b64, p, plen)) < 0) { explicit_bzero(p, plen); free(p); return SSH_ERR_INVALID_FORMAT; } if ((r = sshbuf_put(buf, p, nlen)) < 0) { explicit_bzero(p, plen); free(p); return r; } explicit_bzero(p, plen); free(p); return 0; } openssh-7.2p2/sshbuf.c010064400017500001750000000222241267006270000131120ustar00djmdjm/* $OpenBSD: sshbuf.c,v 1.6 2016/01/12 23:42:54 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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. */ #define SSHBUF_INTERNAL #include "includes.h" #include /* roundup */ #include #include #include #include #include #include "ssherr.h" #include "sshbuf.h" static inline int sshbuf_check_sanity(const struct sshbuf *buf) { SSHBUF_TELL("sanity"); if (__predict_false(buf == NULL || (!buf->readonly && buf->d != buf->cd) || buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX || buf->cd == NULL || (buf->dont_free && (buf->readonly || buf->parent != NULL)) || buf->max_size > SSHBUF_SIZE_MAX || buf->alloc > buf->max_size || buf->size > buf->alloc || buf->off > buf->size)) { /* Do not try to recover from corrupted buffer internals */ SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); signal(SIGSEGV, SIG_DFL); raise(SIGSEGV); return SSH_ERR_INTERNAL_ERROR; } return 0; } static void sshbuf_maybe_pack(struct sshbuf *buf, int force) { SSHBUF_DBG(("force %d", force)); SSHBUF_TELL("pre-pack"); if (buf->off == 0 || buf->readonly || buf->refcount > 1) return; if (force || (buf->off >= SSHBUF_PACK_MIN && buf->off >= buf->size / 2)) { memmove(buf->d, buf->d + buf->off, buf->size - buf->off); buf->size -= buf->off; buf->off = 0; SSHBUF_TELL("packed"); } } struct sshbuf * sshbuf_new(void) { struct sshbuf *ret; if ((ret = calloc(sizeof(*ret), 1)) == NULL) return NULL; ret->alloc = SSHBUF_SIZE_INIT; ret->max_size = SSHBUF_SIZE_MAX; ret->readonly = 0; ret->refcount = 1; ret->parent = NULL; if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) { free(ret); return NULL; } return ret; } struct sshbuf * sshbuf_from(const void *blob, size_t len) { struct sshbuf *ret; if (blob == NULL || len > SSHBUF_SIZE_MAX || (ret = calloc(sizeof(*ret), 1)) == NULL) return NULL; ret->alloc = ret->size = ret->max_size = len; ret->readonly = 1; ret->refcount = 1; ret->parent = NULL; ret->cd = blob; ret->d = NULL; return ret; } int sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent) { int r; if ((r = sshbuf_check_sanity(child)) != 0 || (r = sshbuf_check_sanity(parent)) != 0) return r; child->parent = parent; child->parent->refcount++; return 0; } struct sshbuf * sshbuf_fromb(struct sshbuf *buf) { struct sshbuf *ret; if (sshbuf_check_sanity(buf) != 0) return NULL; if ((ret = sshbuf_from(sshbuf_ptr(buf), sshbuf_len(buf))) == NULL) return NULL; if (sshbuf_set_parent(ret, buf) != 0) { sshbuf_free(ret); return NULL; } return ret; } void sshbuf_init(struct sshbuf *ret) { explicit_bzero(ret, sizeof(*ret)); ret->alloc = SSHBUF_SIZE_INIT; ret->max_size = SSHBUF_SIZE_MAX; ret->readonly = 0; ret->dont_free = 1; ret->refcount = 1; if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) ret->alloc = 0; } void sshbuf_free(struct sshbuf *buf) { int dont_free = 0; if (buf == NULL) return; /* * The following will leak on insane buffers, but this is the safest * course of action - an invalid pointer or already-freed pointer may * have been passed to us and continuing to scribble over memory would * be bad. */ if (sshbuf_check_sanity(buf) != 0) return; /* * If we are a child, the free our parent to decrement its reference * count and possibly free it. */ sshbuf_free(buf->parent); buf->parent = NULL; /* * If we are a parent with still-extant children, then don't free just * yet. The last child's call to sshbuf_free should decrement our * refcount to 0 and trigger the actual free. */ buf->refcount--; if (buf->refcount > 0) return; dont_free = buf->dont_free; if (!buf->readonly) { explicit_bzero(buf->d, buf->alloc); free(buf->d); } explicit_bzero(buf, sizeof(*buf)); if (!dont_free) free(buf); } void sshbuf_reset(struct sshbuf *buf) { u_char *d; if (buf->readonly || buf->refcount > 1) { /* Nonsensical. Just make buffer appear empty */ buf->off = buf->size; return; } if (sshbuf_check_sanity(buf) == 0) explicit_bzero(buf->d, buf->alloc); buf->off = buf->size = 0; if (buf->alloc != SSHBUF_SIZE_INIT) { if ((d = realloc(buf->d, SSHBUF_SIZE_INIT)) != NULL) { buf->cd = buf->d = d; buf->alloc = SSHBUF_SIZE_INIT; } } } size_t sshbuf_max_size(const struct sshbuf *buf) { return buf->max_size; } size_t sshbuf_alloc(const struct sshbuf *buf) { return buf->alloc; } const struct sshbuf * sshbuf_parent(const struct sshbuf *buf) { return buf->parent; } u_int sshbuf_refcount(const struct sshbuf *buf) { return buf->refcount; } int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size) { size_t rlen; u_char *dp; int r; SSHBUF_DBG(("set max buf = %p len = %zu", buf, max_size)); if ((r = sshbuf_check_sanity(buf)) != 0) return r; if (max_size == buf->max_size) return 0; if (buf->readonly || buf->refcount > 1) return SSH_ERR_BUFFER_READ_ONLY; if (max_size > SSHBUF_SIZE_MAX) return SSH_ERR_NO_BUFFER_SPACE; /* pack and realloc if necessary */ sshbuf_maybe_pack(buf, max_size < buf->size); if (max_size < buf->alloc && max_size > buf->size) { if (buf->size < SSHBUF_SIZE_INIT) rlen = SSHBUF_SIZE_INIT; else rlen = roundup(buf->size, SSHBUF_SIZE_INC); if (rlen > max_size) rlen = max_size; explicit_bzero(buf->d + buf->size, buf->alloc - buf->size); SSHBUF_DBG(("new alloc = %zu", rlen)); if ((dp = realloc(buf->d, rlen)) == NULL) return SSH_ERR_ALLOC_FAIL; buf->cd = buf->d = dp; buf->alloc = rlen; } SSHBUF_TELL("new-max"); if (max_size < buf->alloc) return SSH_ERR_NO_BUFFER_SPACE; buf->max_size = max_size; return 0; } size_t sshbuf_len(const struct sshbuf *buf) { if (sshbuf_check_sanity(buf) != 0) return 0; return buf->size - buf->off; } size_t sshbuf_avail(const struct sshbuf *buf) { if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1) return 0; return buf->max_size - (buf->size - buf->off); } const u_char * sshbuf_ptr(const struct sshbuf *buf) { if (sshbuf_check_sanity(buf) != 0) return NULL; return buf->cd + buf->off; } u_char * sshbuf_mutable_ptr(const struct sshbuf *buf) { if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1) return NULL; return buf->d + buf->off; } int sshbuf_check_reserve(const struct sshbuf *buf, size_t len) { int r; if ((r = sshbuf_check_sanity(buf)) != 0) return r; if (buf->readonly || buf->refcount > 1) return SSH_ERR_BUFFER_READ_ONLY; SSHBUF_TELL("check"); /* Check that len is reasonable and that max_size + available < len */ if (len > buf->max_size || buf->max_size - len < buf->size - buf->off) return SSH_ERR_NO_BUFFER_SPACE; return 0; } int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp) { size_t rlen, need; u_char *dp; int r; if (dpp != NULL) *dpp = NULL; SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len)); if ((r = sshbuf_check_reserve(buf, len)) != 0) return r; /* * If the requested allocation appended would push us past max_size * then pack the buffer, zeroing buf->off. */ sshbuf_maybe_pack(buf, buf->size + len > buf->max_size); SSHBUF_TELL("reserve"); if (len + buf->size > buf->alloc) { /* * Prefer to alloc in SSHBUF_SIZE_INC units, but * allocate less if doing so would overflow max_size. */ need = len + buf->size - buf->alloc; rlen = roundup(buf->alloc + need, SSHBUF_SIZE_INC); SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen)); if (rlen > buf->max_size) rlen = buf->alloc + need; SSHBUF_DBG(("adjusted rlen %zu", rlen)); if ((dp = realloc(buf->d, rlen)) == NULL) { SSHBUF_DBG(("realloc fail")); if (dpp != NULL) *dpp = NULL; return SSH_ERR_ALLOC_FAIL; } buf->alloc = rlen; buf->cd = buf->d = dp; if ((r = sshbuf_check_reserve(buf, len)) < 0) { /* shouldn't fail */ if (dpp != NULL) *dpp = NULL; return r; } } dp = buf->d + buf->size; buf->size += len; SSHBUF_TELL("done"); if (dpp != NULL) *dpp = dp; return 0; } int sshbuf_consume(struct sshbuf *buf, size_t len) { int r; SSHBUF_DBG(("len = %zu", len)); if ((r = sshbuf_check_sanity(buf)) != 0) return r; if (len == 0) return 0; if (len > sshbuf_len(buf)) return SSH_ERR_MESSAGE_INCOMPLETE; buf->off += len; SSHBUF_TELL("done"); return 0; } int sshbuf_consume_end(struct sshbuf *buf, size_t len) { int r; SSHBUF_DBG(("len = %zu", len)); if ((r = sshbuf_check_sanity(buf)) != 0) return r; if (len == 0) return 0; if (len > sshbuf_len(buf)) return SSH_ERR_MESSAGE_INCOMPLETE; buf->size -= len; SSHBUF_TELL("done"); return 0; } openssh-7.2p2/sshbuf.h010064400017500001750000000265261267006270000131300ustar00djmdjm/* $OpenBSD: sshbuf.h,v 1.6 2015/12/10 07:01:35 mmcc Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _SSHBUF_H #define _SSHBUF_H #include #include #include #ifdef WITH_OPENSSL # include # ifdef OPENSSL_HAS_ECC # include # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ #define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ #define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */ #define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */ #define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */ /* * NB. do not depend on the internals of this. It will be made opaque * one day. */ struct sshbuf { u_char *d; /* Data */ const u_char *cd; /* Const data */ size_t off; /* First available byte is buf->d + buf->off */ size_t size; /* Last byte is buf->d + buf->size - 1 */ size_t max_size; /* Maximum size of buffer */ size_t alloc; /* Total bytes allocated to buf->d */ int readonly; /* Refers to external, const data */ int dont_free; /* Kludge to support sshbuf_init */ u_int refcount; /* Tracks self and number of child buffers */ struct sshbuf *parent; /* If child, pointer to parent */ }; #ifndef SSHBUF_NO_DEPREACTED /* * NB. Please do not use sshbuf_init() in new code. Please use sshbuf_new() * instead. sshbuf_init() is deprectated and will go away soon (it is * only included to allow compat with buffer_* in OpenSSH) */ void sshbuf_init(struct sshbuf *buf); #endif /* * Create a new sshbuf buffer. * Returns pointer to buffer on success, or NULL on allocation failure. */ struct sshbuf *sshbuf_new(void); /* * Create a new, read-only sshbuf buffer from existing data. * Returns pointer to buffer on success, or NULL on allocation failure. */ struct sshbuf *sshbuf_from(const void *blob, size_t len); /* * Create a new, read-only sshbuf buffer from the contents of an existing * buffer. The contents of "buf" must not change in the lifetime of the * resultant buffer. * Returns pointer to buffer on success, or NULL on allocation failure. */ struct sshbuf *sshbuf_fromb(struct sshbuf *buf); /* * Create a new, read-only sshbuf buffer from the contents of a string in * an existing buffer (the string is consumed in the process). * The contents of "buf" must not change in the lifetime of the resultant * buffer. * Returns pointer to buffer on success, or NULL on allocation failure. */ int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp); /* * Clear and free buf */ void sshbuf_free(struct sshbuf *buf); /* * Reset buf, clearing its contents. NB. max_size is preserved. */ void sshbuf_reset(struct sshbuf *buf); /* * Return the maximum size of buf */ size_t sshbuf_max_size(const struct sshbuf *buf); /* * Set the maximum size of buf * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size); /* * Returns the length of data in buf */ size_t sshbuf_len(const struct sshbuf *buf); /* * Returns number of bytes left in buffer before hitting max_size. */ size_t sshbuf_avail(const struct sshbuf *buf); /* * Returns a read-only pointer to the start of the data in buf */ const u_char *sshbuf_ptr(const struct sshbuf *buf); /* * Returns a mutable pointer to the start of the data in buf, or * NULL if the buffer is read-only. */ u_char *sshbuf_mutable_ptr(const struct sshbuf *buf); /* * Check whether a reservation of size len will succeed in buf * Safer to use than direct comparisons again sshbuf_avail as it copes * with unsigned overflows correctly. * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_check_reserve(const struct sshbuf *buf, size_t len); /* * Reserve len bytes in buf. * Returns 0 on success and a pointer to the first reserved byte via the * optional dpp parameter or a negative * SSH_ERR_* error code on failure. */ int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp); /* * Consume len bytes from the start of buf * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_consume(struct sshbuf *buf, size_t len); /* * Consume len bytes from the end of buf * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_consume_end(struct sshbuf *buf, size_t len); /* Extract or deposit some bytes */ int sshbuf_get(struct sshbuf *buf, void *v, size_t len); int sshbuf_put(struct sshbuf *buf, const void *v, size_t len); int sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v); /* Append using a printf(3) format */ int sshbuf_putf(struct sshbuf *buf, const char *fmt, ...) __attribute__((format(printf, 2, 3))); int sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap); /* Functions to extract or store big-endian words of various sizes */ int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp); int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp); int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp); int sshbuf_get_u8(struct sshbuf *buf, u_char *valp); int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val); int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val); int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val); int sshbuf_put_u8(struct sshbuf *buf, u_char val); /* * Functions to extract or store SSH wire encoded strings (u32 len || data) * The "cstring" variants admit no \0 characters in the string contents. * Caller must free *valp. */ int sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp); int sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp); int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v); int sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len); int sshbuf_put_cstring(struct sshbuf *buf, const char *v); int sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v); /* * "Direct" variant of sshbuf_get_string, returns pointer into the sshbuf to * avoid an malloc+memcpy. The pointer is guaranteed to be valid until the * next sshbuf-modifying function call. Caller does not free. */ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp); /* Skip past a string */ #define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL) /* Another variant: "peeks" into the buffer without modifying it */ int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, size_t *lenp); /* * Functions to extract or store SSH wire encoded bignums and elliptic * curve points. */ int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len); int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp); #ifdef WITH_OPENSSL int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v); int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v); int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v); int sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v); # ifdef OPENSSL_HAS_ECC int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g); int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v); int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g); int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v); # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ /* Dump the contents of the buffer in a human-readable format */ void sshbuf_dump(struct sshbuf *buf, FILE *f); /* Dump specified memory in a human-readable format */ void sshbuf_dump_data(const void *s, size_t len, FILE *f); /* Return the hexadecimal representation of the contents of the buffer */ char *sshbuf_dtob16(struct sshbuf *buf); /* Encode the contents of the buffer as base64 */ char *sshbuf_dtob64(struct sshbuf *buf); /* Decode base64 data and append it to the buffer */ int sshbuf_b64tod(struct sshbuf *buf, const char *b64); /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ ((u_int64_t)(((const u_char *)(p))[1]) << 48) | \ ((u_int64_t)(((const u_char *)(p))[2]) << 40) | \ ((u_int64_t)(((const u_char *)(p))[3]) << 32) | \ ((u_int64_t)(((const u_char *)(p))[4]) << 24) | \ ((u_int64_t)(((const u_char *)(p))[5]) << 16) | \ ((u_int64_t)(((const u_char *)(p))[6]) << 8) | \ (u_int64_t)(((const u_char *)(p))[7])) #define PEEK_U32(p) \ (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \ ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \ ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \ (u_int32_t)(((const u_char *)(p))[3])) #define PEEK_U16(p) \ (((u_int16_t)(((const u_char *)(p))[0]) << 8) | \ (u_int16_t)(((const u_char *)(p))[1])) #define POKE_U64(p, v) \ do { \ const u_int64_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 56) & 0xff; \ ((u_char *)(p))[1] = (__v >> 48) & 0xff; \ ((u_char *)(p))[2] = (__v >> 40) & 0xff; \ ((u_char *)(p))[3] = (__v >> 32) & 0xff; \ ((u_char *)(p))[4] = (__v >> 24) & 0xff; \ ((u_char *)(p))[5] = (__v >> 16) & 0xff; \ ((u_char *)(p))[6] = (__v >> 8) & 0xff; \ ((u_char *)(p))[7] = __v & 0xff; \ } while (0) #define POKE_U32(p, v) \ do { \ const u_int32_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 24) & 0xff; \ ((u_char *)(p))[1] = (__v >> 16) & 0xff; \ ((u_char *)(p))[2] = (__v >> 8) & 0xff; \ ((u_char *)(p))[3] = __v & 0xff; \ } while (0) #define POKE_U16(p, v) \ do { \ const u_int16_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 8) & 0xff; \ ((u_char *)(p))[1] = __v & 0xff; \ } while (0) /* Internal definitions follow. Exposed for regress tests */ #ifdef SSHBUF_INTERNAL /* * Return the allocation size of buf */ size_t sshbuf_alloc(const struct sshbuf *buf); /* * Increment the reference count of buf. */ int sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent); /* * Return the parent buffer of buf, or NULL if it has no parent. */ const struct sshbuf *sshbuf_parent(const struct sshbuf *buf); /* * Return the reference count of buf */ u_int sshbuf_refcount(const struct sshbuf *buf); # define SSHBUF_SIZE_INIT 256 /* Initial allocation */ # define SSHBUF_SIZE_INC 256 /* Preferred increment length */ # define SSHBUF_PACK_MIN 8192 /* Minimim packable offset */ /* # define SSHBUF_ABORT abort */ /* # define SSHBUF_DEBUG */ # ifndef SSHBUF_ABORT # define SSHBUF_ABORT() # endif # ifdef SSHBUF_DEBUG # define SSHBUF_TELL(what) do { \ printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \ __FILE__, __LINE__, __func__, what, \ buf->size, buf->alloc, buf->off, buf->max_size); \ fflush(stdout); \ } while (0) # define SSHBUF_DBG(x) do { \ printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ printf x; \ printf("\n"); \ fflush(stdout); \ } while (0) # else # define SSHBUF_TELL(what) # define SSHBUF_DBG(x) # endif #endif /* SSHBUF_INTERNAL */ #endif /* _SSHBUF_H */ openssh-7.2p2/sshconnect.c010064400017500001750000001244521267006270000137750ustar00djmdjm/* $OpenBSD: sshconnect.c,v 1.271 2016/01/14 22:56:56 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Code to connect to a remote host, and to perform the client side of the * login (authentication) dialog. * * 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 /* roundup */ #include #include #include #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #include #include "xmalloc.h" #include "key.h" #include "hostfile.h" #include "ssh.h" #include "rsa.h" #include "buffer.h" #include "packet.h" #include "uidswap.h" #include "compat.h" #include "key.h" #include "sshconnect.h" #include "hostfile.h" #include "log.h" #include "misc.h" #include "readconf.h" #include "atomicio.h" #include "dns.h" #include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" #include "authfile.h" #include "ssherr.h" #include "authfd.h" char *client_version_string = NULL; char *server_version_string = NULL; Key *previous_host_key = NULL; static int matching_host_key_dns = 0; static pid_t proxy_command_pid = 0; /* import */ extern Options options; extern char *__progname; extern uid_t original_real_uid; extern uid_t original_effective_uid; static int show_other_keys(struct hostkeys *, Key *); static void warn_changed_key(Key *); /* Expand a proxy command */ static char * expand_proxy_command(const char *proxy_command, const char *user, const char *host, int port) { char *tmp, *ret, strport[NI_MAXSERV]; snprintf(strport, sizeof strport, "%d", port); xasprintf(&tmp, "exec %s", proxy_command); ret = percent_expand(tmp, "h", host, "p", strport, "r", options.user, (char *)NULL); free(tmp); return ret; } /* * Connect to the given ssh server using a proxy command that passes a * a connected fd back to us. */ static int ssh_proxy_fdpass_connect(const char *host, u_short port, const char *proxy_command) { char *command_string; int sp[2], sock; pid_t pid; char *shell; if ((shell = getenv("SHELL")) == NULL) shell = _PATH_BSHELL; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) fatal("Could not create socketpair to communicate with " "proxy dialer: %.100s", strerror(errno)); command_string = expand_proxy_command(proxy_command, options.user, host, port); debug("Executing proxy dialer command: %.500s", command_string); /* Fork and execute the proxy command. */ if ((pid = fork()) == 0) { char *argv[10]; /* Child. Permanently give up superuser privileges. */ permanently_drop_suid(original_real_uid); close(sp[1]); /* Redirect stdin and stdout. */ if (sp[0] != 0) { if (dup2(sp[0], 0) < 0) perror("dup2 stdin"); } if (sp[0] != 1) { if (dup2(sp[0], 1) < 0) perror("dup2 stdout"); } if (sp[0] >= 2) close(sp[0]); /* * Stderr is left as it is so that error messages get * printed on the user's terminal. */ argv[0] = shell; argv[1] = "-c"; argv[2] = command_string; argv[3] = NULL; /* * Execute the proxy command. * Note that we gave up any extra privileges above. */ execv(argv[0], argv); perror(argv[0]); exit(1); } /* Parent. */ if (pid < 0) fatal("fork failed: %.100s", strerror(errno)); close(sp[0]); free(command_string); if ((sock = mm_receive_fd(sp[1])) == -1) fatal("proxy dialer did not pass back a connection"); close(sp[1]); while (waitpid(pid, NULL, 0) == -1) if (errno != EINTR) fatal("Couldn't wait for child: %s", strerror(errno)); /* Set the connection file descriptors. */ packet_set_connection(sock, sock); return 0; } /* * Connect to the given ssh server using a proxy command. */ static int ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) { char *command_string; int pin[2], pout[2]; pid_t pid; char *shell; if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; /* Create pipes for communicating with the proxy. */ if (pipe(pin) < 0 || pipe(pout) < 0) fatal("Could not create pipes to communicate with the proxy: %.100s", strerror(errno)); command_string = expand_proxy_command(proxy_command, options.user, host, port); debug("Executing proxy command: %.500s", command_string); /* Fork and execute the proxy command. */ if ((pid = fork()) == 0) { char *argv[10]; /* Child. Permanently give up superuser privileges. */ permanently_drop_suid(original_real_uid); /* Redirect stdin and stdout. */ close(pin[1]); if (pin[0] != 0) { if (dup2(pin[0], 0) < 0) perror("dup2 stdin"); close(pin[0]); } close(pout[0]); if (dup2(pout[1], 1) < 0) perror("dup2 stdout"); /* Cannot be 1 because pin allocated two descriptors. */ close(pout[1]); /* Stderr is left as it is so that error messages get printed on the user's terminal. */ argv[0] = shell; argv[1] = "-c"; argv[2] = command_string; argv[3] = NULL; /* Execute the proxy command. Note that we gave up any extra privileges above. */ signal(SIGPIPE, SIG_DFL); execv(argv[0], argv); perror(argv[0]); exit(1); } /* Parent. */ if (pid < 0) fatal("fork failed: %.100s", strerror(errno)); else proxy_command_pid = pid; /* save pid to clean up later */ /* Close child side of the descriptors. */ close(pin[0]); close(pout[1]); /* Free the command name. */ free(command_string); /* Set the connection file descriptors. */ packet_set_connection(pout[0], pin[1]); /* Indicate OK return */ return 0; } void ssh_kill_proxy_command(void) { /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child */ if (proxy_command_pid > 1) kill(proxy_command_pid, SIGHUP); } /* * Creates a (possibly privileged) socket for use as the ssh connection. */ static int ssh_create_socket(int privileged, struct addrinfo *ai) { int sock, r, gaierr; struct addrinfo hints, *res = NULL; sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { error("socket: %s", strerror(errno)); return -1; } fcntl(sock, F_SETFD, FD_CLOEXEC); /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL && !privileged) return sock; if (options.bind_address) { memset(&hints, 0, sizeof(hints)); hints.ai_family = ai->ai_family; hints.ai_socktype = ai->ai_socktype; hints.ai_protocol = ai->ai_protocol; hints.ai_flags = AI_PASSIVE; gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); if (gaierr) { error("getaddrinfo: %s: %s", options.bind_address, ssh_gai_strerror(gaierr)); close(sock); return -1; } } /* * If we are running as root and want to connect to a privileged * port, bind our own socket to a privileged port. */ if (privileged) { PRIV_START; r = bindresvport_sa(sock, res ? res->ai_addr : NULL); PRIV_END; if (r < 0) { error("bindresvport_sa: af=%d %s", ai->ai_family, strerror(errno)); goto fail; } } else { if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { error("bind: %s: %s", options.bind_address, strerror(errno)); fail: close(sock); freeaddrinfo(res); return -1; } } if (res != NULL) freeaddrinfo(res); return sock; } static int timeout_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen, int *timeoutp) { fd_set *fdset; struct timeval tv, t_start; socklen_t optlen; int optval, rc, result = -1; gettimeofday(&t_start, NULL); if (*timeoutp <= 0) { result = connect(sockfd, serv_addr, addrlen); goto done; } set_nonblock(sockfd); rc = connect(sockfd, serv_addr, addrlen); if (rc == 0) { unset_nonblock(sockfd); result = 0; goto done; } if (errno != EINPROGRESS) { result = -1; goto done; } fdset = xcalloc(howmany(sockfd + 1, NFDBITS), sizeof(fd_mask)); FD_SET(sockfd, fdset); ms_to_timeval(&tv, *timeoutp); for (;;) { rc = select(sockfd + 1, NULL, fdset, NULL, &tv); if (rc != -1 || errno != EINTR) break; } switch (rc) { case 0: /* Timed out */ errno = ETIMEDOUT; break; case -1: /* Select error */ debug("select: %s", strerror(errno)); break; case 1: /* Completed or failed */ optval = 0; optlen = sizeof(optval); if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { debug("getsockopt: %s", strerror(errno)); break; } if (optval != 0) { errno = optval; break; } result = 0; unset_nonblock(sockfd); break; default: /* Should not occur */ fatal("Bogus return (%d) from select()", rc); } free(fdset); done: if (result == 0 && *timeoutp > 0) { ms_subtract_diff(&t_start, timeoutp); if (*timeoutp <= 0) { errno = ETIMEDOUT; result = -1; } } return (result); } /* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. * If port is 0, the default port will be used. If needpriv is true, * a privileged port will be allocated to make the connection. * This requires super-user privileges if needpriv is true. * Connection_attempts specifies the maximum number of tries (one per * second). If proxy_command is non-NULL, it specifies the command (with %h * and %p substituted for host and port, respectively) to use to contact * the daemon. */ static int ssh_connect_direct(const char *host, struct addrinfo *aitop, struct sockaddr_storage *hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) { int on = 1; int sock = -1, attempt; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo *ai; debug2("%s: needpriv %d", __func__, needpriv); memset(ntop, 0, sizeof(ntop)); memset(strport, 0, sizeof(strport)); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ sleep(1); debug("Trying again..."); } /* * Loop through addresses for this host, and try each one in * sequence until the connection succeeds. */ for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("%s: getnameinfo failed", __func__); continue; } debug("Connecting to %.200s [%.100s] port %s.", host, ntop, strport); /* Create a socket for connecting. */ sock = ssh_create_socket(needpriv, ai); if (sock < 0) /* Any error is already output */ continue; if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, timeout_ms) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; } else { debug("connect to address %s port %s: %s", ntop, strport, strerror(errno)); close(sock); sock = -1; } } if (sock != -1) break; /* Successful connection. */ } /* Return failure if we didn't get a successful connection. */ if (sock == -1) { error("ssh: connect to host %s port %s: %s", host, strport, strerror(errno)); return (-1); } debug("Connection established."); /* Set SO_KEEPALIVE if requested. */ if (want_keepalive && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); /* Set the connection. */ packet_set_connection(sock, sock); return 0; } int ssh_connect(const char *host, struct addrinfo *addrs, struct sockaddr_storage *hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) { if (options.proxy_command == NULL) { return ssh_connect_direct(host, addrs, hostaddr, port, family, connection_attempts, timeout_ms, want_keepalive, needpriv); } else if (strcmp(options.proxy_command, "-") == 0) { packet_set_connection(STDIN_FILENO, STDOUT_FILENO); return 0; /* Always succeeds */ } else if (options.proxy_use_fdpass) { return ssh_proxy_fdpass_connect(host, port, options.proxy_command); } return ssh_proxy_connect(host, port, options.proxy_command); } static void send_client_banner(int connection_out, int minor1) { /* Send our own protocol version identification. */ if (compat20) { xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); } else { xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", PROTOCOL_MAJOR_1, minor1, SSH_VERSION); } if (atomicio(vwrite, connection_out, client_version_string, strlen(client_version_string)) != strlen(client_version_string)) fatal("write: %.100s", strerror(errno)); chop(client_version_string); debug("Local version string %.100s", client_version_string); } /* * Waits for the server identification string, and sends our own * identification string. */ void ssh_exchange_identification(int timeout_ms) { char buf[256], remote_version[256]; /* must be same size! */ int remote_major, remote_minor, mismatch; int connection_in = packet_get_connection_in(); int connection_out = packet_get_connection_out(); int minor1 = PROTOCOL_MINOR_1, client_banner_sent = 0; u_int i, n; size_t len; int fdsetsz, remaining, rc; struct timeval t_start, t_remaining; fd_set *fdset; fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask); fdset = xcalloc(1, fdsetsz); /* * If we are SSH2-only then we can send the banner immediately and * save a round-trip. */ if (options.protocol == SSH_PROTO_2) { enable_compat20(); send_client_banner(connection_out, 0); client_banner_sent = 1; } /* Read other side's version identification. */ remaining = timeout_ms; for (n = 0;;) { for (i = 0; i < sizeof(buf) - 1; i++) { if (timeout_ms > 0) { gettimeofday(&t_start, NULL); ms_to_timeval(&t_remaining, remaining); FD_SET(connection_in, fdset); rc = select(connection_in + 1, fdset, NULL, fdset, &t_remaining); ms_subtract_diff(&t_start, &remaining); if (rc == 0 || remaining <= 0) fatal("Connection timed out during " "banner exchange"); if (rc == -1) { if (errno == EINTR) continue; fatal("ssh_exchange_identification: " "select: %s", strerror(errno)); } } len = atomicio(read, connection_in, &buf[i], 1); if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: " "Connection closed by remote host"); else if (len != 1) fatal("ssh_exchange_identification: " "read: %.100s", strerror(errno)); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; continue; /**XXX wait for \n */ } if (buf[i] == '\n') { buf[i + 1] = 0; break; } if (++n > 65536) fatal("ssh_exchange_identification: " "No banner received"); } buf[sizeof(buf) - 1] = 0; if (strncmp(buf, "SSH-", 4) == 0) break; debug("ssh_exchange_identification: %s", buf); } server_version_string = xstrdup(buf); free(fdset); /* * Check that the versions match. In future this might accept * several versions and set appropriate flags to handle them. */ if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) fatal("Bad remote protocol version identification: '%.100s'", buf); debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); active_state->compat = compat_datafellows(remote_version); mismatch = 0; switch (remote_major) { case 1: if (remote_minor == 99 && (options.protocol & SSH_PROTO_2) && !(options.protocol & SSH_PROTO_1_PREFERRED)) { enable_compat20(); break; } if (!(options.protocol & SSH_PROTO_1)) { mismatch = 1; break; } if (remote_minor < 3) { fatal("Remote machine has too old SSH software version."); } else if (remote_minor == 3 || remote_minor == 4) { /* We speak 1.3, too. */ enable_compat13(); minor1 = 3; if (options.forward_agent) { logit("Agent forwarding disabled for protocol 1.3"); options.forward_agent = 0; } } break; case 2: if (options.protocol & SSH_PROTO_2) { enable_compat20(); break; } /* FALLTHROUGH */ default: mismatch = 1; break; } if (mismatch) fatal("Protocol major versions differ: %d vs. %d", (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, remote_major); if ((datafellows & SSH_BUG_DERIVEKEY) != 0) fatal("Server version \"%.100s\" uses unsafe key agreement; " "refusing connection", remote_version); if ((datafellows & SSH_BUG_RSASIGMD5) != 0) logit("Server version \"%.100s\" uses unsafe RSA signature " "scheme; disabling use of RSA keys", remote_version); if (!client_banner_sent) send_client_banner(connection_out, minor1); chop(server_version_string); } /* defaults to 'no' */ static int confirm(const char *prompt) { const char *msg, *again = "Please type 'yes' or 'no': "; char *p; int ret = -1; if (options.batch_mode) return 0; for (msg = prompt;;msg = again) { p = read_passphrase(msg, RP_ECHO); if (p == NULL || (p[0] == '\0') || (p[0] == '\n') || strncasecmp(p, "no", 2) == 0) ret = 0; if (p && strncasecmp(p, "yes", 3) == 0) ret = 1; free(p); if (ret != -1) return ret; } } static int check_host_cert(const char *host, const Key *host_key) { const char *reason; if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { error("%s", reason); return 0; } if (buffer_len(host_key->cert->critical) != 0) { error("Certificate for %s contains unsupported " "critical options(s)", host); return 0; } return 1; } static int sockaddr_is_local(struct sockaddr *hostaddr) { switch (hostaddr->sa_family) { case AF_INET: return (ntohl(((struct sockaddr_in *)hostaddr)-> sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; case AF_INET6: return IN6_IS_ADDR_LOOPBACK( &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); default: return 0; } } /* * Prepare the hostname and ip address strings that are used to lookup * host keys in known_hosts files. These may have a port number appended. */ void get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, u_short port, char **hostfile_hostname, char **hostfile_ipaddr) { char ntop[NI_MAXHOST]; socklen_t addrlen; switch (hostaddr == NULL ? -1 : hostaddr->sa_family) { case -1: addrlen = 0; break; case AF_INET: addrlen = sizeof(struct sockaddr_in); break; case AF_INET6: addrlen = sizeof(struct sockaddr_in6); break; default: addrlen = sizeof(struct sockaddr); break; } /* * We don't have the remote ip-address for connections * using a proxy command */ if (hostfile_ipaddr != NULL) { if (options.proxy_command == NULL) { if (getnameinfo(hostaddr, addrlen, ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) fatal("%s: getnameinfo failed", __func__); *hostfile_ipaddr = put_host_port(ntop, port); } else { *hostfile_ipaddr = xstrdup(""); } } /* * Allow the user to record the key under a different name or * differentiate a non-standard port. This is useful for ssh * tunneling over forwarded connections or if you run multiple * sshd's on different ports on the same machine. */ if (hostfile_hostname != NULL) { if (options.host_key_alias != NULL) { *hostfile_hostname = xstrdup(options.host_key_alias); debug("using hostkeyalias: %s", *hostfile_hostname); } else { *hostfile_hostname = put_host_port(hostname, port); } } } /* * check whether the supplied host key is valid, return -1 if the key * is not valid. user_hostfile[0] will not be updated if 'readonly' is true. */ #define RDRW 0 #define RDONLY 1 #define ROQUIET 2 static int check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Key *host_key, int readonly, char **user_hostfiles, u_int num_user_hostfiles, char **system_hostfiles, u_int num_system_hostfiles) { HostStatus host_status; HostStatus ip_status; Key *raw_key = NULL; char *ip = NULL, *host = NULL; char hostline[1000], *hostp, *fp, *ra; char msg[1024]; const char *type; const struct hostkey_entry *host_found, *ip_found; int len, cancelled_forwarding = 0; int local = sockaddr_is_local(hostaddr); int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; int hostkey_trusted = 0; /* Known or explicitly accepted by user */ struct hostkeys *host_hostkeys, *ip_hostkeys; u_int i; /* * Force accepting of the host key for loopback/localhost. The * problem is that if the home directory is NFS-mounted to multiple * machines, localhost will refer to a different machine in each of * them, and the user will get bogus HOST_CHANGED warnings. This * essentially disables host authentication for localhost; however, * this is probably not a real problem. */ if (options.no_host_authentication_for_localhost == 1 && local && options.host_key_alias == NULL) { debug("Forcing accepting of host key for " "loopback/localhost."); return 0; } /* * Prepare the hostname and address strings used for hostkey lookup. * In some cases, these will have a port number appended. */ get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip); /* * Turn off check_host_ip if the connection is to localhost, via proxy * command or if we don't have a hostname to compare with */ if (options.check_host_ip && (local || strcmp(hostname, ip) == 0 || options.proxy_command != NULL)) options.check_host_ip = 0; host_hostkeys = init_hostkeys(); for (i = 0; i < num_user_hostfiles; i++) load_hostkeys(host_hostkeys, host, user_hostfiles[i]); for (i = 0; i < num_system_hostfiles; i++) load_hostkeys(host_hostkeys, host, system_hostfiles[i]); ip_hostkeys = NULL; if (!want_cert && options.check_host_ip) { ip_hostkeys = init_hostkeys(); for (i = 0; i < num_user_hostfiles; i++) load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); for (i = 0; i < num_system_hostfiles; i++) load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); } retry: /* Reload these as they may have changed on cert->key downgrade */ want_cert = key_is_cert(host_key); type = key_type(host_key); /* * Check if the host key is present in the user's list of known * hosts or in the systemwide list. */ host_status = check_key_in_hostkeys(host_hostkeys, host_key, &host_found); /* * Also perform check for the ip address, skip the check if we are * localhost, looking for a certificate, or the hostname was an ip * address to begin with. */ if (!want_cert && ip_hostkeys != NULL) { ip_status = check_key_in_hostkeys(ip_hostkeys, host_key, &ip_found); if (host_status == HOST_CHANGED && (ip_status != HOST_CHANGED || (ip_found != NULL && !key_equal(ip_found->key, host_found->key)))) host_ip_differ = 1; } else ip_status = host_status; switch (host_status) { case HOST_OK: /* The host is known and the key matches. */ debug("Host '%.200s' is known and matches the %s host %s.", host, type, want_cert ? "certificate" : "key"); debug("Found %s in %s:%lu", want_cert ? "CA key" : "key", host_found->file, host_found->line); if (want_cert && !check_host_cert(hostname, host_key)) goto fail; if (options.check_host_ip && ip_status == HOST_NEW) { if (readonly || want_cert) logit("%s host key for IP address " "'%.128s' not in list of known hosts.", type, ip); else if (!add_host_to_hostfile(user_hostfiles[0], ip, host_key, options.hash_known_hosts)) logit("Failed to add the %s host key for IP " "address '%.128s' to the list of known " "hosts (%.500s).", type, ip, user_hostfiles[0]); else logit("Warning: Permanently added the %s host " "key for IP address '%.128s' to the list " "of known hosts.", type, ip); } else if (options.visual_host_key) { fp = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_DEFAULT); ra = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("Host key fingerprint is %s\n%s", fp, ra); free(ra); free(fp); } hostkey_trusted = 1; break; case HOST_NEW: if (options.host_key_alias == NULL && port != 0 && port != SSH_DEFAULT_PORT) { debug("checking without port identifier"); if (check_host_key(hostname, hostaddr, 0, host_key, ROQUIET, user_hostfiles, num_user_hostfiles, system_hostfiles, num_system_hostfiles) == 0) { debug("found matching key w/out port"); break; } } if (readonly || want_cert) goto fail; /* The host is new. */ if (options.strict_host_key_checking == 1) { /* * User has requested strict host key checking. We * will not add the host key automatically. The only * alternative left is to abort. */ error("No %s host key is known for %.200s and you " "have requested strict checking.", type, host); goto fail; } else if (options.strict_host_key_checking == 2) { char msg1[1024], msg2[1024]; if (show_other_keys(host_hostkeys, host_key)) snprintf(msg1, sizeof(msg1), "\nbut keys of different type are already" " known for this host."); else snprintf(msg1, sizeof(msg1), "."); /* The default */ fp = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_DEFAULT); ra = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) snprintf(msg2, sizeof(msg2), "Matching host key fingerprint" " found in DNS.\n"); else snprintf(msg2, sizeof(msg2), "No matching host key fingerprint" " found in DNS.\n"); } snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" "%s key fingerprint is %s.%s%s\n%s" "Are you sure you want to continue connecting " "(yes/no)? ", host, ip, msg1, type, fp, options.visual_host_key ? "\n" : "", options.visual_host_key ? ra : "", msg2); free(ra); free(fp); if (!confirm(msg)) goto fail; hostkey_trusted = 1; /* user explicitly confirmed */ } /* * If not in strict mode, add the key automatically to the * local known_hosts file. */ if (options.check_host_ip && ip_status == HOST_NEW) { snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); hostp = hostline; if (options.hash_known_hosts) { /* Add hash of host and IP separately */ r = add_host_to_hostfile(user_hostfiles[0], host, host_key, options.hash_known_hosts) && add_host_to_hostfile(user_hostfiles[0], ip, host_key, options.hash_known_hosts); } else { /* Add unhashed "host,ip" */ r = add_host_to_hostfile(user_hostfiles[0], hostline, host_key, options.hash_known_hosts); } } else { r = add_host_to_hostfile(user_hostfiles[0], host, host_key, options.hash_known_hosts); hostp = host; } if (!r) logit("Failed to add the host to the list of known " "hosts (%.500s).", user_hostfiles[0]); else logit("Warning: Permanently added '%.200s' (%s) to the " "list of known hosts.", hostp, type); break; case HOST_REVOKED: error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REVOKED HOST KEY DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The %s host key for %s is marked as revoked.", type, host); error("This could mean that a stolen key is being used to"); error("impersonate this host."); /* * If strict host key checking is in use, the user will have * to edit the key manually and we can only abort. */ if (options.strict_host_key_checking) { error("%s host key for %.200s was revoked and you have " "requested strict checking.", type, host); goto fail; } goto continue_unsafe; case HOST_CHANGED: if (want_cert) { /* * This is only a debug() since it is valid to have * CAs with wildcard DNS matches that don't match * all hosts that one might visit. */ debug("Host certificate authority does not " "match %s in %s:%lu", CA_MARKER, host_found->file, host_found->line); goto fail; } if (readonly == ROQUIET) goto fail; if (options.check_host_ip && host_ip_differ) { char *key_msg; if (ip_status == HOST_NEW) key_msg = "is unknown"; else if (ip_status == HOST_OK) key_msg = "is unchanged"; else key_msg = "has a different value"; error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The %s host key for %s has changed,", type, host); error("and the key for the corresponding IP address %s", ip); error("%s. This could either mean that", key_msg); error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); if (ip_status != HOST_NEW) error("Offending key for IP in %s:%lu", ip_found->file, ip_found->line); } /* The host key has changed. */ warn_changed_key(host_key); error("Add correct host key in %.100s to get rid of this message.", user_hostfiles[0]); error("Offending %s key in %s:%lu", key_type(host_found->key), host_found->file, host_found->line); /* * If strict host key checking is in use, the user will have * to edit the key manually and we can only abort. */ if (options.strict_host_key_checking) { error("%s host key for %.200s has changed and you have " "requested strict checking.", type, host); goto fail; } continue_unsafe: /* * If strict host key checking has not been requested, allow * the connection but without MITM-able authentication or * forwarding. */ if (options.password_authentication) { error("Password authentication is disabled to avoid " "man-in-the-middle attacks."); options.password_authentication = 0; cancelled_forwarding = 1; } if (options.kbd_interactive_authentication) { error("Keyboard-interactive authentication is disabled" " to avoid man-in-the-middle attacks."); options.kbd_interactive_authentication = 0; options.challenge_response_authentication = 0; cancelled_forwarding = 1; } if (options.challenge_response_authentication) { error("Challenge/response authentication is disabled" " to avoid man-in-the-middle attacks."); options.challenge_response_authentication = 0; cancelled_forwarding = 1; } if (options.forward_agent) { error("Agent forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_agent = 0; cancelled_forwarding = 1; } if (options.forward_x11) { error("X11 forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_x11 = 0; cancelled_forwarding = 1; } if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) { error("Port forwarding is disabled to avoid " "man-in-the-middle attacks."); options.num_local_forwards = options.num_remote_forwards = 0; cancelled_forwarding = 1; } if (options.tun_open != SSH_TUNMODE_NO) { error("Tunnel forwarding is disabled to avoid " "man-in-the-middle attacks."); options.tun_open = SSH_TUNMODE_NO; cancelled_forwarding = 1; } if (options.exit_on_forward_failure && cancelled_forwarding) fatal("Error: forwarding disabled due to host key " "check failure"); /* * XXX Should permit the user to change to use the new id. * This could be done by converting the host key to an * identifying sentence, tell that the host identifies itself * by that sentence, and ask the user if he/she wishes to * accept the authentication. */ break; case HOST_FOUND: fatal("internal error"); break; } if (options.check_host_ip && host_status != HOST_CHANGED && ip_status == HOST_CHANGED) { snprintf(msg, sizeof(msg), "Warning: the %s host key for '%.200s' " "differs from the key for the IP address '%.128s'" "\nOffending key for IP in %s:%lu", type, host, ip, ip_found->file, ip_found->line); if (host_status == HOST_OK) { len = strlen(msg); snprintf(msg + len, sizeof(msg) - len, "\nMatching host key in %s:%lu", host_found->file, host_found->line); } if (options.strict_host_key_checking == 1) { logit("%s", msg); error("Exiting, you have requested strict checking."); goto fail; } else if (options.strict_host_key_checking == 2) { strlcat(msg, "\nAre you sure you want " "to continue connecting (yes/no)? ", sizeof(msg)); if (!confirm(msg)) goto fail; } else { logit("%s", msg); } } if (!hostkey_trusted && options.update_hostkeys) { debug("%s: hostkey not known or explicitly trusted: " "disabling UpdateHostkeys", __func__); options.update_hostkeys = 0; } free(ip); free(host); if (host_hostkeys != NULL) free_hostkeys(host_hostkeys); if (ip_hostkeys != NULL) free_hostkeys(ip_hostkeys); return 0; fail: if (want_cert && host_status != HOST_REVOKED) { /* * No matching certificate. Downgrade cert to raw key and * search normally. */ debug("No matching CA found. Retry with plain key"); raw_key = key_from_private(host_key); if (key_drop_cert(raw_key) != 0) fatal("Couldn't drop certificate"); host_key = raw_key; goto retry; } if (raw_key != NULL) key_free(raw_key); free(ip); free(host); if (host_hostkeys != NULL) free_hostkeys(host_hostkeys); if (ip_hostkeys != NULL) free_hostkeys(ip_hostkeys); return -1; } /* returns 0 if key verifies or -1 if key does NOT verify */ int verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { u_int i; int r = -1, flags = 0; char valid[64], *fp = NULL, *cafp = NULL; struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: fingerprint host key: %s", __func__, ssh_err(r)); r = -1; goto out; } if (sshkey_is_cert(host_key)) { if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: fingerprint CA key: %s", __func__, ssh_err(r)); r = -1; goto out; } sshkey_format_cert_validity(host_key->cert, valid, sizeof(valid)); debug("Server host certificate: %s %s, serial %llu " "ID \"%s\" CA %s %s valid %s", sshkey_ssh_name(host_key), fp, (unsigned long long)host_key->cert->serial, host_key->cert->key_id, sshkey_ssh_name(host_key->cert->signature_key), cafp, valid); for (i = 0; i < host_key->cert->nprincipals; i++) { debug2("Server host certificate hostname: %s", host_key->cert->principals[i]); } } else { debug("Server host key: %s %s", compat20 ? sshkey_ssh_name(host_key) : sshkey_type(host_key), fp); } if (sshkey_equal(previous_host_key, host_key)) { debug2("%s: server host key %s %s matches cached key", __func__, sshkey_type(host_key), fp); r = 0; goto out; } /* Check in RevokedHostKeys file if specified */ if (options.revoked_host_keys != NULL) { r = sshkey_check_revoked(host_key, options.revoked_host_keys); switch (r) { case 0: break; /* not revoked */ case SSH_ERR_KEY_REVOKED: error("Host key %s %s revoked by file %s", sshkey_type(host_key), fp, options.revoked_host_keys); r = -1; goto out; default: error("Error checking host key %s %s in " "revoked keys file %s: %s", sshkey_type(host_key), fp, options.revoked_host_keys, ssh_err(r)); r = -1; goto out; } } if (options.verify_host_key_dns) { /* * XXX certs are not yet supported for DNS, so downgrade * them and try the plain key. */ if ((r = sshkey_from_private(host_key, &plain)) != 0) goto out; if (sshkey_is_cert(plain)) sshkey_drop_cert(plain); if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { if (flags & DNS_VERIFY_FOUND) { if (options.verify_host_key_dns == 1 && flags & DNS_VERIFY_MATCH && flags & DNS_VERIFY_SECURE) { r = 0; goto out; } if (flags & DNS_VERIFY_MATCH) { matching_host_key_dns = 1; } else { warn_changed_key(plain); error("Update the SSHFP RR in DNS " "with the new host key to get rid " "of this message."); } } } } r = check_host_key(host, hostaddr, options.port, host_key, RDRW, options.user_hostfiles, options.num_user_hostfiles, options.system_hostfiles, options.num_system_hostfiles); out: sshkey_free(plain); free(fp); free(cafp); if (r == 0 && host_key != NULL) { key_free(previous_host_key); previous_host_key = key_from_private(host_key); } return r; } /* * Starts a dialog with the server, and authenticates the current user on the * server. This does not need any extra privileges. The basic connection * to the server must already have been established before this is called. * If login fails, this function prints an error and never returns. * This function does not require super-user privileges. */ void ssh_login(Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) { char *host; char *server_user, *local_user; local_user = xstrdup(pw->pw_name); server_user = options.user ? options.user : local_user; /* Convert the user-supplied hostname into all lowercase. */ host = xstrdup(orighost); lowercase(host); /* Exchange protocol version identification strings with the server. */ ssh_exchange_identification(timeout_ms); /* Put the connection into non-blocking mode. */ packet_set_nonblocking(); /* key exchange */ /* authenticate user */ debug("Authenticating to %s:%d as '%s'", host, port, server_user); if (compat20) { ssh_kex2(host, hostaddr, port); ssh_userauth2(local_user, server_user, host, sensitive); } else { #ifdef WITH_SSH1 ssh_kex(host, hostaddr); ssh_userauth1(local_user, server_user, host, sensitive); #else fatal("ssh1 is not supported"); #endif } free(local_user); } void ssh_put_password(char *password) { int size; char *padded; if (datafellows & SSH_BUG_PASSWORDPAD) { packet_put_cstring(password); return; } size = roundup(strlen(password) + 1, 32); padded = xcalloc(1, size); strlcpy(padded, password, size); packet_put_string(padded, size); explicit_bzero(padded, size); free(padded); } /* print all known host keys for a given host, but skip keys of given type */ static int show_other_keys(struct hostkeys *hostkeys, Key *key) { int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, -1 }; int i, ret = 0; char *fp, *ra; const struct hostkey_entry *found; for (i = 0; type[i] != -1; i++) { if (type[i] == key->type) continue; if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; fp = sshkey_fingerprint(found->key, options.fingerprint_hash, SSH_FP_DEFAULT); ra = sshkey_fingerprint(found->key, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" "in %s:%lu\n" "%s key fingerprint %s.", key_type(found->key), found->host, found->file, found->line, key_type(found->key), fp); if (options.visual_host_key) logit("%s", ra); free(ra); free(fp); ret = 1; } return ret; } static void warn_changed_key(Key *host_key) { char *fp; fp = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_DEFAULT); if (fp == NULL) fatal("%s: sshkey_fingerprint fail", __func__); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); error("It is also possible that a host key has just been changed."); error("The fingerprint for the %s key sent by the remote host is\n%s.", key_type(host_key), fp); error("Please contact your system administrator."); free(fp); } /* * Execute a local command */ int ssh_local_cmd(const char *args) { char *shell; pid_t pid; int status; void (*osighand)(int); if (!options.permit_local_command || args == NULL || !*args) return (1); if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; osighand = signal(SIGCHLD, SIG_DFL); pid = fork(); if (pid == 0) { signal(SIGPIPE, SIG_DFL); debug3("Executing %s -c \"%s\"", shell, args); execl(shell, shell, "-c", args, (char *)NULL); error("Couldn't execute %s -c \"%s\": %s", shell, args, strerror(errno)); _exit(1); } else if (pid == -1) fatal("fork failed: %.100s", strerror(errno)); while (waitpid(pid, &status, 0) == -1) if (errno != EINTR) fatal("Couldn't wait for child: %s", strerror(errno)); signal(SIGCHLD, osighand); if (!WIFEXITED(status)) return (1); return (WEXITSTATUS(status)); } void maybe_add_key_to_agent(char *authfile, Key *private, char *comment, char *passphrase) { int auth_sock = -1, r; if (options.add_keys_to_agent == 0) return; if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { debug3("no authentication agent, not adding key"); return; } if (options.add_keys_to_agent == 2 && !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { debug3("user denied adding this key"); return; } if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0, (options.add_keys_to_agent == 3))) == 0) debug("identity added to agent: %s", authfile); else debug("could not add identity to agent: %s (%d)", authfile, r); } openssh-7.2p2/sshconnect.h010064400017500001750000000053271267006270000140010ustar00djmdjm/* $OpenBSD: sshconnect.h,v 1.29 2015/11/15 22:26:49 jcs 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. */ typedef struct Sensitive Sensitive; struct Sensitive { Key **keys; int nkeys; int external_keysign; }; struct addrinfo; int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *, u_short, int, int, int *, int, int); void ssh_kill_proxy_command(void); void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, struct passwd *, int); void ssh_exchange_identification(int); int verify_host_key(char *, struct sockaddr *, Key *); void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, char **, char **); void ssh_kex(char *, struct sockaddr *); void ssh_kex2(char *, struct sockaddr *, u_short); void ssh_userauth1(const char *, const char *, char *, Sensitive *); void ssh_userauth2(const char *, const char *, char *, Sensitive *); void ssh_put_password(char *); int ssh_local_cmd(const char *); void maybe_add_key_to_agent(char *, Key *, char *, char *); /* * Macros to raise/lower permissions. */ #define PRIV_START do { \ int save_errno = errno; \ if (seteuid(original_effective_uid) != 0) \ fatal("PRIV_START: seteuid: %s", \ strerror(errno)); \ errno = save_errno; \ } while (0) #define PRIV_END do { \ int save_errno = errno; \ if (seteuid(original_real_uid) != 0) \ fatal("PRIV_END: seteuid: %s", \ strerror(errno)); \ errno = save_errno; \ } while (0) openssh-7.2p2/sshconnect1.c010064400017500001750000000543231267006270000140550ustar00djmdjm/* $OpenBSD: sshconnect1.c,v 1.78 2015/11/15 22:26:49 jcs Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Code to connect to a remote host, and to perform the client side of the * login (authentication) dialog. * * 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" #ifdef WITH_SSH1 #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "rsa.h" #include "buffer.h" #include "packet.h" #include "key.h" #include "cipher.h" #include "kex.h" #include "uidswap.h" #include "log.h" #include "misc.h" #include "readconf.h" #include "authfd.h" #include "sshconnect.h" #include "authfile.h" #include "canohost.h" #include "hostfile.h" #include "auth.h" #include "digest.h" #include "ssherr.h" /* Session id for the current session. */ u_char session_id[16]; u_int supported_authentications = 0; extern Options options; extern char *__progname; /* * Checks if the user has an authentication agent, and if so, tries to * authenticate using the agent. */ static int try_agent_authentication(void) { int r, type, agent_fd, ret = 0; u_char response[16]; size_t i; BIGNUM *challenge; struct ssh_identitylist *idlist = NULL; /* Get connection to the agent. */ if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); return 0; } if ((challenge = BN_new()) == NULL) fatal("try_agent_authentication: BN_new failed"); /* Loop through identities served by the agent. */ if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) { if (r != SSH_ERR_AGENT_NO_IDENTITIES) debug("%s: ssh_fetch_identitylist: %s", __func__, ssh_err(r)); goto out; } for (i = 0; i < idlist->nkeys; i++) { /* Try this identity. */ debug("Trying RSA authentication via agent with '%.100s'", idlist->comments[i]); /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); packet_put_bignum(idlist->keys[i]->rsa->n); packet_send(); packet_write_wait(); /* Wait for server's response. */ type = packet_read(); /* The server sends failure if it doesn't like our key or does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); continue; } /* Otherwise it should have sent a challenge. */ if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) packet_disconnect("Protocol error during RSA authentication: %d", type); packet_get_bignum(challenge); packet_check_eom(); debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i], challenge, session_id, response)) != 0) { /* * The agent failed to authenticate this identifier * although it advertised it supports this. Just * return a wrong value. */ logit("Authentication agent failed to decrypt " "challenge: %s", ssh_err(r)); explicit_bzero(response, sizeof(response)); } debug("Sending response to RSA challenge."); /* Send the decrypted challenge back to the server. */ packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); for (i = 0; i < 16; i++) packet_put_char(response[i]); packet_send(); packet_write_wait(); /* Wait for response from the server. */ type = packet_read(); /* * The server returns success if it accepted the * authentication. */ if (type == SSH_SMSG_SUCCESS) { debug("RSA authentication accepted by server."); ret = 1; break; } else if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error waiting RSA auth " "response: %d", type); } if (ret != 1) debug("RSA authentication using agent refused."); out: ssh_free_identitylist(idlist); ssh_close_authentication_socket(agent_fd); BN_clear_free(challenge); return ret; } /* * Computes the proper response to a RSA challenge, and sends the response to * the server. */ static void respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) { u_char buf[32], response[16]; struct ssh_digest_ctx *md; int i, len; /* Decrypt the challenge using the private key. */ /* XXX think about Bleichenbacher, too */ if (rsa_private_decrypt(challenge, challenge, prv) != 0) packet_disconnect( "respond_to_rsa_challenge: rsa_private_decrypt failed"); /* Compute the response. */ /* The response is MD5 of decrypted challenge plus session id. */ len = BN_num_bytes(challenge); if (len <= 0 || (u_int)len > sizeof(buf)) packet_disconnect( "respond_to_rsa_challenge: bad challenge length %d", len); memset(buf, 0, sizeof(buf)); BN_bn2bin(challenge, buf + sizeof(buf) - len); if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || ssh_digest_update(md, buf, 32) < 0 || ssh_digest_update(md, session_id, 16) < 0 || ssh_digest_final(md, response, sizeof(response)) < 0) fatal("%s: md5 failed", __func__); ssh_digest_free(md); debug("Sending response to host key RSA challenge."); /* Send the response back to the server. */ packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); for (i = 0; i < 16; i++) packet_put_char(response[i]); packet_send(); packet_write_wait(); explicit_bzero(buf, sizeof(buf)); explicit_bzero(response, sizeof(response)); explicit_bzero(&md, sizeof(md)); } /* * Checks if the user has authentication file, and if so, tries to authenticate * the user using it. */ static int try_rsa_authentication(int idx) { BIGNUM *challenge; Key *public, *private; char buf[300], *passphrase = NULL, *comment, *authfile; int i, perm_ok = 1, type, quit; public = options.identity_keys[idx]; authfile = options.identity_files[idx]; comment = xstrdup(authfile); debug("Trying RSA authentication with key '%.100s'", comment); /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); packet_put_bignum(public->rsa->n); packet_send(); packet_write_wait(); /* Wait for server's response. */ type = packet_read(); /* * The server responds with failure if it doesn't like our key or * doesn't support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); free(comment); return 0; } /* Otherwise, the server should respond with a challenge. */ if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) packet_disconnect("Protocol error during RSA authentication: %d", type); /* Get the challenge from the packet. */ if ((challenge = BN_new()) == NULL) fatal("try_rsa_authentication: BN_new failed"); packet_get_bignum(challenge); packet_check_eom(); debug("Received RSA challenge from server."); /* * If the key is not stored in external hardware, we have to * load the private key. Try first with empty passphrase; if it * fails, ask for a passphrase. */ if (public->flags & SSHKEY_FLAG_EXT) private = public; else private = key_load_private_type(KEY_RSA1, authfile, "", NULL, &perm_ok); if (private == NULL && !options.batch_mode && perm_ok) { snprintf(buf, sizeof(buf), "Enter passphrase for RSA key '%.100s': ", comment); for (i = 0; i < options.number_of_password_prompts; i++) { passphrase = read_passphrase(buf, 0); if (strcmp(passphrase, "") != 0) { private = key_load_private_type(KEY_RSA1, authfile, passphrase, NULL, NULL); quit = 0; } else { debug2("no passphrase given, try next key"); quit = 1; } if (private != NULL || quit) break; debug2("bad passphrase given, try again..."); } } if (private != NULL) maybe_add_key_to_agent(authfile, private, comment, passphrase); if (passphrase != NULL) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); } /* We no longer need the comment. */ free(comment); if (private == NULL) { if (!options.batch_mode && perm_ok) error("Bad passphrase."); /* Send a dummy response packet to avoid protocol error. */ packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); for (i = 0; i < 16; i++) packet_put_char(0); packet_send(); packet_write_wait(); /* Expect the server to reject it... */ packet_read_expect(SSH_SMSG_FAILURE); BN_clear_free(challenge); return 0; } /* Compute and send a response to the challenge. */ respond_to_rsa_challenge(challenge, private->rsa); /* Destroy the private key unless it in external hardware. */ if (!(private->flags & SSHKEY_FLAG_EXT)) key_free(private); /* We no longer need the challenge. */ BN_clear_free(challenge); /* Wait for response from the server. */ type = packet_read(); if (type == SSH_SMSG_SUCCESS) { debug("RSA authentication accepted by server."); return 1; } if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error waiting RSA auth response: %d", type); debug("RSA authentication refused."); return 0; } /* * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv * authentication and RSA host authentication. */ static int try_rhosts_rsa_authentication(const char *local_user, Key * host_key) { int type; BIGNUM *challenge; debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); packet_put_cstring(local_user); packet_put_int(BN_num_bits(host_key->rsa->n)); packet_put_bignum(host_key->rsa->e); packet_put_bignum(host_key->rsa->n); packet_send(); packet_write_wait(); /* Wait for server's response. */ type = packet_read(); /* The server responds with failure if it doesn't admit our .rhosts authentication or doesn't know our host key. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our rhosts authentication or host key."); return 0; } /* Otherwise, the server should respond with a challenge. */ if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) packet_disconnect("Protocol error during RSA authentication: %d", type); /* Get the challenge from the packet. */ if ((challenge = BN_new()) == NULL) fatal("try_rhosts_rsa_authentication: BN_new failed"); packet_get_bignum(challenge); packet_check_eom(); debug("Received RSA challenge for host key from server."); /* Compute a response to the challenge. */ respond_to_rsa_challenge(challenge, host_key->rsa); /* We no longer need the challenge. */ BN_clear_free(challenge); /* Wait for response from the server. */ type = packet_read(); if (type == SSH_SMSG_SUCCESS) { debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); return 1; } if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error waiting RSA auth response: %d", type); debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); return 0; } /* * Tries to authenticate with any string-based challenge/response system. * Note that the client code is not tied to s/key or TIS. */ static int try_challenge_response_authentication(void) { int type, i; u_int clen; char prompt[1024]; char *challenge, *response; debug("Doing challenge response authentication."); for (i = 0; i < options.number_of_password_prompts; i++) { /* request a challenge */ packet_start(SSH_CMSG_AUTH_TIS); packet_send(); packet_write_wait(); type = packet_read(); if (type != SSH_SMSG_FAILURE && type != SSH_SMSG_AUTH_TIS_CHALLENGE) { packet_disconnect("Protocol error: got %d in response " "to SSH_CMSG_AUTH_TIS", type); } if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { debug("No challenge."); return 0; } challenge = packet_get_string(&clen); packet_check_eom(); snprintf(prompt, sizeof prompt, "%s%s", challenge, strchr(challenge, '\n') ? "" : "\nResponse: "); free(challenge); if (i != 0) error("Permission denied, please try again."); if (options.cipher == SSH_CIPHER_NONE) logit("WARNING: Encryption is disabled! " "Response will be transmitted in clear text."); response = read_passphrase(prompt, 0); if (strcmp(response, "") == 0) { free(response); break; } packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); ssh_put_password(response); explicit_bzero(response, strlen(response)); free(response); packet_send(); packet_write_wait(); type = packet_read(); if (type == SSH_SMSG_SUCCESS) return 1; if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error: got %d in response " "to SSH_CMSG_AUTH_TIS_RESPONSE", type); } /* failure */ return 0; } /* * Tries to authenticate with plain passwd authentication. */ static int try_password_authentication(char *prompt) { int type, i; char *password; debug("Doing password authentication."); if (options.cipher == SSH_CIPHER_NONE) logit("WARNING: Encryption is disabled! Password will be transmitted in clear text."); for (i = 0; i < options.number_of_password_prompts; i++) { if (i != 0) error("Permission denied, please try again."); password = read_passphrase(prompt, 0); packet_start(SSH_CMSG_AUTH_PASSWORD); ssh_put_password(password); explicit_bzero(password, strlen(password)); free(password); packet_send(); packet_write_wait(); type = packet_read(); if (type == SSH_SMSG_SUCCESS) return 1; if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error: got %d in response to passwd auth", type); } /* failure */ return 0; } /* * SSH1 key exchange */ void ssh_kex(char *host, struct sockaddr *hostaddr) { int i; BIGNUM *key; Key *host_key, *server_key; int bits, rbits; int ssh_cipher_default = SSH_CIPHER_3DES; u_char session_key[SSH_SESSION_KEY_LENGTH]; u_char cookie[8]; u_int supported_ciphers; u_int server_flags, client_flags; u_int32_t rnd = 0; debug("Waiting for server public key."); /* Wait for a public key packet from the server. */ packet_read_expect(SSH_SMSG_PUBLIC_KEY); /* Get cookie from the packet. */ for (i = 0; i < 8; i++) cookie[i] = packet_get_char(); /* Get the public key. */ server_key = key_new(KEY_RSA1); bits = packet_get_int(); packet_get_bignum(server_key->rsa->e); packet_get_bignum(server_key->rsa->n); rbits = BN_num_bits(server_key->rsa->n); if (bits != rbits) { logit("Warning: Server lies about size of server public key: " "actual size is %d bits vs. announced %d.", rbits, bits); logit("Warning: This may be due to an old implementation of ssh."); } /* Get the host key. */ host_key = key_new(KEY_RSA1); bits = packet_get_int(); packet_get_bignum(host_key->rsa->e); packet_get_bignum(host_key->rsa->n); rbits = BN_num_bits(host_key->rsa->n); if (bits != rbits) { logit("Warning: Server lies about size of server host key: " "actual size is %d bits vs. announced %d.", rbits, bits); logit("Warning: This may be due to an old implementation of ssh."); } /* Get protocol flags. */ server_flags = packet_get_int(); packet_set_protocol_flags(server_flags); supported_ciphers = packet_get_int(); supported_authentications = packet_get_int(); packet_check_eom(); debug("Received server public key (%d bits) and host key (%d bits).", BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); if (verify_host_key(host, hostaddr, host_key) == -1) fatal("Host key verification failed."); client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); /* * Generate an encryption key for the session. The key is a 256 bit * random number, interpreted as a 32-byte key, with the least * significant 8 bits being the first byte of the key. */ for (i = 0; i < 32; i++) { if (i % 4 == 0) rnd = arc4random(); session_key[i] = rnd & 0xff; rnd >>= 8; } /* * According to the protocol spec, the first byte of the session key * is the highest byte of the integer. The session key is xored with * the first 16 bytes of the session id. */ if ((key = BN_new()) == NULL) fatal("ssh_kex: BN_new failed"); if (BN_set_word(key, 0) == 0) fatal("ssh_kex: BN_set_word failed"); for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { if (BN_lshift(key, key, 8) == 0) fatal("ssh_kex: BN_lshift failed"); if (i < 16) { if (BN_add_word(key, session_key[i] ^ session_id[i]) == 0) fatal("ssh_kex: BN_add_word failed"); } else { if (BN_add_word(key, session_key[i]) == 0) fatal("ssh_kex: BN_add_word failed"); } } /* * Encrypt the integer using the public key and host key of the * server (key with smaller modulus first). */ if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { /* Public key has smaller modulus. */ if (BN_num_bits(host_key->rsa->n) < BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " "SSH_KEY_BITS_RESERVED %d", BN_num_bits(host_key->rsa->n), BN_num_bits(server_key->rsa->n), SSH_KEY_BITS_RESERVED); } if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || rsa_public_encrypt(key, key, host_key->rsa) != 0) fatal("%s: rsa_public_encrypt failed", __func__); } else { /* Host key has smaller modulus (or they are equal). */ if (BN_num_bits(server_key->rsa->n) < BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " "SSH_KEY_BITS_RESERVED %d", BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n), SSH_KEY_BITS_RESERVED); } if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || rsa_public_encrypt(key, key, server_key->rsa) != 0) fatal("%s: rsa_public_encrypt failed", __func__); } /* Destroy the public keys since we no longer need them. */ key_free(server_key); key_free(host_key); if (options.cipher == SSH_CIPHER_NOT_SET) { if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) options.cipher = ssh_cipher_default; } else if (options.cipher == SSH_CIPHER_INVALID || !(cipher_mask_ssh1(1) & (1 << options.cipher))) { logit("No valid SSH1 cipher, using %.100s instead.", cipher_name(ssh_cipher_default)); options.cipher = ssh_cipher_default; } /* Check that the selected cipher is supported. */ if (!(supported_ciphers & (1 << options.cipher))) fatal("Selected cipher type %.100s not supported by server.", cipher_name(options.cipher)); debug("Encryption type: %.100s", cipher_name(options.cipher)); /* Send the encrypted session key to the server. */ packet_start(SSH_CMSG_SESSION_KEY); packet_put_char(options.cipher); /* Send the cookie back to the server. */ for (i = 0; i < 8; i++) packet_put_char(cookie[i]); /* Send and destroy the encrypted encryption key integer. */ packet_put_bignum(key); BN_clear_free(key); /* Send protocol flags. */ packet_put_int(client_flags); /* Send the packet now. */ packet_send(); packet_write_wait(); debug("Sent encrypted session key."); /* Set the encryption key. */ packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); /* * We will no longer need the session key here. * Destroy any extra copies. */ explicit_bzero(session_key, sizeof(session_key)); /* * Expect a success message from the server. Note that this message * will be received in encrypted form. */ packet_read_expect(SSH_SMSG_SUCCESS); debug("Received encrypted confirmation."); } /* * Authenticate user */ void ssh_userauth1(const char *local_user, const char *server_user, char *host, Sensitive *sensitive) { int i, type; if (supported_authentications == 0) fatal("ssh_userauth1: server supports no auth methods"); /* Send the name of the user to log in as on the server. */ packet_start(SSH_CMSG_USER); packet_put_cstring(server_user); packet_send(); packet_write_wait(); /* * The server should respond with success if no authentication is * needed (the user has no password). Otherwise the server responds * with failure. */ type = packet_read(); /* check whether the connection was accepted without authentication. */ if (type == SSH_SMSG_SUCCESS) goto success; if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); /* * Try .rhosts or /etc/hosts.equiv authentication with RSA host * authentication. */ if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && options.rhosts_rsa_authentication) { for (i = 0; i < sensitive->nkeys; i++) { if (sensitive->keys[i] != NULL && sensitive->keys[i]->type == KEY_RSA1 && try_rhosts_rsa_authentication(local_user, sensitive->keys[i])) goto success; } } /* Try RSA authentication if the server supports it. */ if ((supported_authentications & (1 << SSH_AUTH_RSA)) && options.rsa_authentication) { /* * Try RSA authentication using the authentication agent. The * agent is tried first because no passphrase is needed for * it, whereas identity files may require passphrases. */ if (try_agent_authentication()) goto success; /* Try RSA authentication for each identity. */ for (i = 0; i < options.num_identity_files; i++) if (options.identity_keys[i] != NULL && options.identity_keys[i]->type == KEY_RSA1 && try_rsa_authentication(i)) goto success; } /* Try challenge response authentication if the server supports it. */ if ((supported_authentications & (1 << SSH_AUTH_TIS)) && options.challenge_response_authentication && !options.batch_mode) { if (try_challenge_response_authentication()) goto success; } /* Try password authentication if the server supports it. */ if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && options.password_authentication && !options.batch_mode) { char prompt[80]; snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", server_user, host); if (try_password_authentication(prompt)) goto success; } /* All authentication methods have failed. Exit with an error message. */ fatal("Permission denied."); /* NOTREACHED */ success: return; /* need statement after label */ } #endif /* WITH_SSH1 */ openssh-7.2p2/sshconnect2.c010064400017500001750000001453731267006270000140640ustar00djmdjm/* $OpenBSD: sshconnect2.c,v 1.239 2016/02/23 01:34:14 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) #include #endif #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" #include "buffer.h" #include "packet.h" #include "compat.h" #include "cipher.h" #include "key.h" #include "kex.h" #include "myproposal.h" #include "sshconnect.h" #include "authfile.h" #include "dh.h" #include "authfd.h" #include "log.h" #include "misc.h" #include "readconf.h" #include "match.h" #include "dispatch.h" #include "canohost.h" #include "msg.h" #include "pathnames.h" #include "uidswap.h" #include "hostfile.h" #include "ssherr.h" #ifdef GSSAPI #include "ssh-gss.h" #endif /* import */ extern char *client_version_string; extern char *server_version_string; extern Options options; /* * SSH2 key exchange */ u_char *session_id2 = NULL; u_int session_id2_len = 0; char *xxx_host; struct sockaddr *xxx_hostaddr; static int verify_host_key_callback(Key *hostkey, struct ssh *ssh) { if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) fatal("Host key verification failed."); return 0; } static char * order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) { char *oavail, *avail, *first, *last, *alg, *hostname, *ret; size_t maxlen; struct hostkeys *hostkeys; int ktype; u_int i; /* Find all hostkeys for this hostname */ get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); hostkeys = init_hostkeys(); for (i = 0; i < options.num_user_hostfiles; i++) load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); for (i = 0; i < options.num_system_hostfiles; i++) load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); *first = *last = '\0'; #define ALG_APPEND(to, from) \ do { \ if (*to != '\0') \ strlcat(to, ",", maxlen); \ strlcat(to, from, maxlen); \ } while (0) while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) fatal("%s: unknown alg %s", __func__, alg); if (lookup_key_in_hostkeys_by_type(hostkeys, sshkey_type_plain(ktype), NULL)) ALG_APPEND(first, alg); else ALG_APPEND(last, alg); } #undef ALG_APPEND xasprintf(&ret, "%s%s%s", first, (*first == '\0' || *last == '\0') ? "" : ",", last); if (*first != '\0') debug3("%s: prefer hostkeyalgs: %s", __func__, first); free(first); free(last); free(hostname); free(oavail); free_hostkeys(hostkeys); return ret; } void ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *s; struct kex *kex; int r; xxx_host = host; xxx_hostaddr = hostaddr; if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(options.ciphers); myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(options.ciphers); if (options.compression) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; } else { myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib"; } myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; if (options.hostkeyalgorithms != NULL) { if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &options.hostkeyalgorithms) != 0) fatal("%s: kex_assemble_namelist", __func__); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(options.hostkeyalgorithms); } else { /* Enforce default */ options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); /* Prefer algorithms that we already have keys for */ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( order_hostkeyalgs(host, hostaddr, port)); } if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits((u_int32_t)options.rekey_limit, (time_t)options.rekey_interval); /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); kex = active_state->kex; #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); /* remove ext-info from the KEX proposals for rekeying */ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(options.kex_algorithms); if ((r = kex_prop2buf(kex->my, myproposal)) != 0) fatal("kex_prop2buf: %s", ssh_err(r)); session_id2 = kex->session_id; session_id2_len = kex->session_id_len; #ifdef DEBUG_KEXDH /* send 1st encrypted/maced/compressed message */ packet_start(SSH2_MSG_IGNORE); packet_put_cstring("markus"); packet_send(); packet_write_wait(); #endif } /* * Authenticate user */ typedef struct cauthctxt Authctxt; typedef struct cauthmethod Authmethod; typedef struct identity Identity; typedef struct idlist Idlist; struct identity { TAILQ_ENTRY(identity) next; int agent_fd; /* >=0 if agent supports key */ struct sshkey *key; /* public/private key */ char *filename; /* comment for agent-only keys */ int tried; int isprivate; /* key points to the private key */ int userprovided; }; TAILQ_HEAD(idlist, identity); struct cauthctxt { const char *server_user; const char *local_user; const char *host; const char *service; struct cauthmethod *method; sig_atomic_t success; char *authlist; int attempt; /* pubkey */ struct idlist keys; int agent_fd; /* hostbased */ Sensitive *sensitive; char *oktypes, *ktypes; const char *active_ktype; /* kbd-interactive */ int info_req_seen; /* generic */ void *methoddata; }; struct cauthmethod { char *name; /* string to compare against server's list */ int (*userauth)(Authctxt *authctxt); void (*cleanup)(Authctxt *authctxt); int *enabled; /* flag in option struct that enables method */ int *batch_flag; /* flag in option struct that disables method */ }; int input_userauth_service_accept(int, u_int32_t, void *); int input_userauth_ext_info(int, u_int32_t, void *); int input_userauth_success(int, u_int32_t, void *); int input_userauth_success_unexpected(int, u_int32_t, void *); int input_userauth_failure(int, u_int32_t, void *); int input_userauth_banner(int, u_int32_t, void *); int input_userauth_error(int, u_int32_t, void *); int input_userauth_info_req(int, u_int32_t, void *); int input_userauth_pk_ok(int, u_int32_t, void *); int input_userauth_passwd_changereq(int, u_int32_t, void *); int userauth_none(Authctxt *); int userauth_pubkey(Authctxt *); int userauth_passwd(Authctxt *); int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); #ifdef GSSAPI int userauth_gssapi(Authctxt *authctxt); int input_gssapi_response(int type, u_int32_t, void *); int input_gssapi_token(int type, u_int32_t, void *); int input_gssapi_hash(int type, u_int32_t, void *); int input_gssapi_error(int, u_int32_t, void *); int input_gssapi_errtok(int, u_int32_t, void *); #endif void userauth(Authctxt *, char *); static int sign_and_send_pubkey(Authctxt *, Identity *); static void pubkey_prepare(Authctxt *); static void pubkey_cleanup(Authctxt *); static Key *load_identity_file(Identity *); static Authmethod *authmethod_get(char *authlist); static Authmethod *authmethod_lookup(const char *name); static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI {"gssapi-with-mic", userauth_gssapi, NULL, &options.gss_authentication, NULL}, #endif {"hostbased", userauth_hostbased, NULL, &options.hostbased_authentication, NULL}, {"publickey", userauth_pubkey, NULL, &options.pubkey_authentication, NULL}, {"keyboard-interactive", userauth_kbdint, NULL, &options.kbd_interactive_authentication, &options.batch_mode}, {"password", userauth_passwd, NULL, &options.password_authentication, &options.batch_mode}, {"none", userauth_none, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL} }; void ssh_userauth2(const char *local_user, const char *server_user, char *host, Sensitive *sensitive) { struct ssh *ssh = active_state; Authctxt authctxt; int r; if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; if (options.preferred_authentications == NULL) options.preferred_authentications = authmethods_get(); /* setup authentication context */ memset(&authctxt, 0, sizeof(authctxt)); pubkey_prepare(&authctxt); authctxt.server_user = server_user; authctxt.local_user = local_user; authctxt.host = host; authctxt.service = "ssh-connection"; /* service name */ authctxt.success = 0; authctxt.method = authmethod_lookup("none"); authctxt.authlist = NULL; authctxt.methoddata = NULL; authctxt.sensitive = sensitive; authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL; authctxt.info_req_seen = 0; authctxt.agent_fd = -1; if (authctxt.method == NULL) fatal("ssh_userauth2: internal error: cannot send userauth none request"); if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); ssh_dispatch_init(ssh, &input_userauth_error); ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info); ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept); ssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ pubkey_cleanup(&authctxt); ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); debug("Authentication succeeded (%s).", authctxt.method->name); } /* ARGSUSED */ int input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt) { Authctxt *authctxt = ctxt; struct ssh *ssh = active_state; int r; if (ssh_packet_remaining(ssh) > 0) { char *reply; if ((r = sshpkt_get_cstring(ssh, &reply, NULL)) != 0) goto out; debug2("service_accept: %s", reply); free(reply); } else { debug2("buggy server: service_accept w/o service"); } if ((r = sshpkt_get_end(ssh)) != 0) goto out; debug("SSH2_MSG_SERVICE_ACCEPT received"); /* initial userauth request */ userauth_none(authctxt); ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); r = 0; out: return r; } /* ARGSUSED */ int input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt) { return kex_input_ext_info(type, seqnr, active_state); } void userauth(Authctxt *authctxt, char *authlist) { if (authctxt->method != NULL && authctxt->method->cleanup != NULL) authctxt->method->cleanup(authctxt); free(authctxt->methoddata); authctxt->methoddata = NULL; if (authlist == NULL) { authlist = authctxt->authlist; } else { free(authctxt->authlist); authctxt->authlist = authlist; } for (;;) { Authmethod *method = authmethod_get(authlist); if (method == NULL) fatal("Permission denied (%s).", authlist); authctxt->method = method; /* reset the per method handler */ dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); /* and try new method */ if (method->userauth(authctxt) != 0) { debug2("we sent a %s packet, wait for reply", method->name); break; } else { debug2("we did not send a packet, disable method"); method->enabled = NULL; } } } /* ARGSUSED */ int input_userauth_error(int type, u_int32_t seq, void *ctxt) { fatal("input_userauth_error: bad message during authentication: " "type %d", type); return 0; } /* ARGSUSED */ int input_userauth_banner(int type, u_int32_t seq, void *ctxt) { char *msg, *raw, *lang; u_int len; debug3("input_userauth_banner"); raw = packet_get_string(&len); lang = packet_get_string(NULL); if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { if (len > 65536) len = 65536; msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); fprintf(stderr, "%s", msg); free(msg); } free(raw); free(lang); return 0; } /* ARGSUSED */ int input_userauth_success(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; if (authctxt == NULL) fatal("input_userauth_success: no authentication context"); free(authctxt->authlist); authctxt->authlist = NULL; if (authctxt->method != NULL && authctxt->method->cleanup != NULL) authctxt->method->cleanup(authctxt); free(authctxt->methoddata); authctxt->methoddata = NULL; authctxt->success = 1; /* break out */ return 0; } int input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; if (authctxt == NULL) fatal("%s: no authentication context", __func__); fatal("Unexpected authentication success during %s.", authctxt->method->name); return 0; } /* ARGSUSED */ int input_userauth_failure(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; char *authlist = NULL; int partial; if (authctxt == NULL) fatal("input_userauth_failure: no authentication context"); authlist = packet_get_string(NULL); partial = packet_get_char(); packet_check_eom(); if (partial != 0) { logit("Authenticated with partial success."); /* reset state */ pubkey_cleanup(authctxt); pubkey_prepare(authctxt); } debug("Authentications that can continue: %s", authlist); userauth(authctxt, authlist); return 0; } /* ARGSUSED */ int input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; Key *key = NULL; Identity *id = NULL; Buffer b; int pktype, sent = 0; u_int alen, blen; char *pkalg, *fp; u_char *pkblob; if (authctxt == NULL) fatal("input_userauth_pk_ok: no authentication context"); if (datafellows & SSH_BUG_PKOK) { /* this is similar to SSH_BUG_PKAUTH */ debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } packet_check_eom(); debug("Server accepts key: pkalg %s blen %u", pkalg, blen); if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { debug("unknown pkalg %s", pkalg); goto done; } if ((key = key_from_blob(pkblob, blen)) == NULL) { debug("no key from blob. pkalg %s", pkalg); goto done; } if (key->type != pktype) { error("input_userauth_pk_ok: type mismatch " "for decoded key (received %d, expected %d)", key->type, pktype); goto done; } if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) goto done; debug2("input_userauth_pk_ok: fp %s", fp); free(fp); /* * search keys in the reverse order, because last candidate has been * moved to the end of the queue. this also avoids confusion by * duplicate keys */ TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { if (key_equal(key, id->key)) { sent = sign_and_send_pubkey(authctxt, id); break; } } done: if (key != NULL) key_free(key); free(pkalg); free(pkblob); /* try another method if we did not send a packet */ if (sent == 0) userauth(authctxt, NULL); return 0; } #ifdef GSSAPI int userauth_gssapi(Authctxt *authctxt) { Gssctxt *gssctxt = NULL; static gss_OID_set gss_supported = NULL; static u_int mech = 0; OM_uint32 min; int ok = 0; /* Try one GSSAPI method at a time, rather than sending them all at * once. */ if (gss_supported == NULL) gss_indicate_mechs(&min, &gss_supported); /* Check to see if the mechanism is usable before we offer it */ while (mech < gss_supported->count && !ok) { /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && ssh_gssapi_check_mechanism(&gssctxt, &gss_supported->elements[mech], authctxt->host)) { ok = 1; /* Mechanism works */ } else { mech++; } } if (!ok) return 0; authctxt->methoddata=(void *)gssctxt; packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_int(1); packet_put_int((gss_supported->elements[mech].length) + 2); packet_put_char(SSH_GSS_OIDTYPE); packet_put_char(gss_supported->elements[mech].length); packet_put_raw(gss_supported->elements[mech].elements, gss_supported->elements[mech].length); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); mech++; /* Move along to next candidate */ return 1; } static OM_uint32 process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt = authctxt->methoddata; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; gss_buffer_desc gssbuf; OM_uint32 status, ms, flags; Buffer b; status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, recv_tok, &send_tok, &flags); if (send_tok.length > 0) { if (GSS_ERROR(status)) packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); else packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); packet_put_string(send_tok.value, send_tok.length); packet_send(); gss_release_buffer(&ms, &send_tok); } if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ if (!(flags & GSS_C_INTEG_FLAG)) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); packet_send(); } else { ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, "gssapi-with-mic"); gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); if (!GSS_ERROR(status)) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); packet_put_string(mic.value, mic.length); packet_send(); } buffer_free(&b); gss_release_buffer(&ms, &mic); } } return status; } /* ARGSUSED */ int input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; int oidlen; char *oidv; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; /* Setup our OID */ oidv = packet_get_string(&oidlen); if (oidlen <= 2 || oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen - 2) { free(oidv); debug("Badly encoded mechanism OID received"); userauth(authctxt, NULL); return 0; } if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) fatal("Server returned different OID than expected"); packet_check_eom(); free(oidv); if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { /* Start again with next method on list */ debug("Trying to start again"); userauth(authctxt, NULL); return 0; } return 0; } /* ARGSUSED */ int input_gssapi_token(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; gss_buffer_desc recv_tok; OM_uint32 status; u_int slen; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); recv_tok.value = packet_get_string(&slen); recv_tok.length = slen; /* safe typecast */ packet_check_eom(); status = process_gssapi_token(ctxt, &recv_tok); free(recv_tok.value); if (GSS_ERROR(status)) { /* Start again with the next method in the list */ userauth(authctxt, NULL); return 0; } return 0; } /* ARGSUSED */ int 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 ms; u_int len; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; recv_tok.value = packet_get_string(&len); recv_tok.length = len; packet_check_eom(); /* Stick it into GSSAPI and see what it says */ (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, &recv_tok, &send_tok, NULL); free(recv_tok.value); gss_release_buffer(&ms, &send_tok); /* Server will be returning a failed packet after this one */ return 0; } /* ARGSUSED */ int input_gssapi_error(int type, u_int32_t plen, void *ctxt) { char *msg; char *lang; /* maj */(void)packet_get_int(); /* min */(void)packet_get_int(); msg=packet_get_string(NULL); lang=packet_get_string(NULL); packet_check_eom(); debug("Server GSSAPI Error:\n%s", msg); free(msg); free(lang); return 0; } #endif /* GSSAPI */ int userauth_none(Authctxt *authctxt) { /* initial userauth request */ packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_send(); return 1; } int userauth_passwd(Authctxt *authctxt) { static int attempt = 0; char prompt[150]; char *password; const char *host = options.host_key_alias ? options.host_key_alias : authctxt->host; if (attempt++ >= options.number_of_password_prompts) return 0; if (attempt != 1) error("Permission denied, please try again."); snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", authctxt->server_user, host); password = read_passphrase(prompt, 0); packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_char(0); packet_put_cstring(password); explicit_bzero(password, strlen(password)); free(password); packet_add_padding(64); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq); return 1; } /* * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ /* ARGSUSED */ int input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) { Authctxt *authctxt = ctxt; char *info, *lang, *password = NULL, *retype = NULL; char prompt[150]; const char *host = options.host_key_alias ? options.host_key_alias : authctxt->host; debug2("input_userauth_passwd_changereq"); if (authctxt == NULL) fatal("input_userauth_passwd_changereq: " "no authentication context"); info = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(info) > 0) logit("%s", info); free(info); free(lang); packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_char(1); /* additional info */ snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's old password: ", authctxt->server_user, host); password = read_passphrase(prompt, 0); packet_put_cstring(password); explicit_bzero(password, strlen(password)); free(password); password = NULL; while (password == NULL) { snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's new password: ", authctxt->server_user, host); password = read_passphrase(prompt, RP_ALLOW_EOF); if (password == NULL) { /* bail out */ return 0; } snprintf(prompt, sizeof(prompt), "Retype %.30s@%.128s's new password: ", authctxt->server_user, host); retype = read_passphrase(prompt, 0); if (strcmp(password, retype) != 0) { explicit_bzero(password, strlen(password)); free(password); logit("Mismatch; try again, EOF to quit."); password = NULL; } explicit_bzero(retype, strlen(retype)); free(retype); } packet_put_cstring(password); explicit_bzero(password, strlen(password)); free(password); packet_add_padding(64); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq); return 0; } static const char * identity_sign_encode(struct identity *id) { struct ssh *ssh = active_state; if (id->key->type == KEY_RSA) { switch (ssh->kex->rsa_sha2) { case 256: return "rsa-sha2-256"; case 512: return "rsa-sha2-512"; } } return key_ssh_name(id->key); } static int identity_sign(struct identity *id, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { Key *prv; int ret; const char *alg; alg = identity_sign_encode(id); /* the agent supports this key */ if (id->agent_fd != -1) return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, data, datalen, alg, compat); /* * we have already loaded the private key or * the private key is stored in external hardware */ if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)) return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg, compat)); /* load the private key from the file */ if ((prv = load_identity_file(id)) == NULL) return SSH_ERR_KEY_NOT_FOUND; ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat); sshkey_free(prv); return (ret); } static int sign_and_send_pubkey(Authctxt *authctxt, Identity *id) { Buffer b; Identity *private_id; u_char *blob, *signature; size_t slen; u_int bloblen, skip = 0; int matched, ret = -1, have_sig = 1; char *fp; if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) return 0; debug3("%s: %s %s", __func__, key_type(id->key), fp); free(fp); if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("sign_and_send_pubkey: cannot handle key"); return 0; } /* data to be signed */ buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); skip = session_id2_len; } else { buffer_put_string(&b, session_id2, session_id2_len); skip = buffer_len(&b); } buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->server_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, authctxt->method->name); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, identity_sign_encode(id)); } buffer_put_string(&b, blob, bloblen); /* * If the key is an certificate, try to find a matching private key * and use it to complete the signature. * If no such private key exists, return failure and continue with * other methods of authentication. */ if (key_is_cert(id->key)) { matched = 0; TAILQ_FOREACH(private_id, &authctxt->keys, next) { if (sshkey_equal_public(id->key, private_id->key) && id->key->type != private_id->key->type) { id = private_id; matched = 1; break; } } if (matched) { debug2("%s: using private key \"%s\"%s for " "certificate", __func__, id->filename, id->agent_fd != -1 ? " from agent" : ""); } else { /* XXX maybe verbose/error? */ debug("%s: no private key for certificate " "\"%s\"", __func__, id->filename); free(blob); buffer_free(&b); return 0; } } /* generate signature */ ret = identity_sign(id, &signature, &slen, buffer_ptr(&b), buffer_len(&b), datafellows); if (ret != 0) { if (ret != SSH_ERR_KEY_NOT_FOUND) error("%s: signing failed: %s", __func__, ssh_err(ret)); free(blob); buffer_free(&b); return 0; } #ifdef DEBUG_PK buffer_dump(&b); #endif if (datafellows & SSH_BUG_PKSERVICE) { buffer_clear(&b); buffer_append(&b, session_id2, session_id2_len); skip = session_id2_len; buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->server_user); buffer_put_cstring(&b, authctxt->service); buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) buffer_put_cstring(&b, key_ssh_name(id->key)); buffer_put_string(&b, blob, bloblen); } free(blob); /* append signature */ buffer_put_string(&b, signature, slen); free(signature); /* skip session id and packet type */ if (buffer_len(&b) < skip + 1) fatal("userauth_pubkey: internal error"); buffer_consume(&b, skip + 1); /* put remaining data from buffer into packet */ packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_raw(buffer_ptr(&b), buffer_len(&b)); buffer_free(&b); packet_send(); return 1; } static int send_pubkey_test(Authctxt *authctxt, Identity *id) { u_char *blob; u_int bloblen, have_sig = 0; debug3("send_pubkey_test"); if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("send_pubkey_test: cannot handle key"); return 0; } /* register callback for USERAUTH_PK_OK message */ dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_char(have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) packet_put_cstring(identity_sign_encode(id)); packet_put_string(blob, bloblen); free(blob); packet_send(); return 1; } static Key * load_identity_file(Identity *id) { Key *private = NULL; char prompt[300], *passphrase, *comment; int r, perm_ok = 0, quit = 0, i; struct stat st; if (stat(id->filename, &st) < 0) { (id->userprovided ? logit : debug3)("no such identity: %s: %s", id->filename, strerror(errno)); return NULL; } snprintf(prompt, sizeof prompt, "Enter passphrase for key '%.100s': ", id->filename); for (i = 0; i <= options.number_of_password_prompts; i++) { if (i == 0) passphrase = ""; else { passphrase = read_passphrase(prompt, 0); if (*passphrase == '\0') { debug2("no passphrase given, try next key"); free(passphrase); break; } } switch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename, passphrase, &private, &comment, &perm_ok))) { case 0: break; case SSH_ERR_KEY_WRONG_PASSPHRASE: if (options.batch_mode) { quit = 1; break; } if (i != 0) debug2("bad passphrase given, try again..."); break; case SSH_ERR_SYSTEM_ERROR: if (errno == ENOENT) { debug2("Load key \"%s\": %s", id->filename, ssh_err(r)); quit = 1; break; } /* FALLTHROUGH */ default: error("Load key \"%s\": %s", id->filename, ssh_err(r)); quit = 1; break; } if (!quit && private != NULL && id->agent_fd == -1 && !(id->key && id->isprivate)) maybe_add_key_to_agent(id->filename, private, comment, passphrase); if (i > 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); } free(comment); if (private != NULL || quit) break; } return private; } /* * try keys in the following order: * 1. certificates listed in the config file * 2. other input certificates * 3. agent keys that are found in the config file * 4. other agent keys * 5. keys that are only listed in the config file */ static void pubkey_prepare(Authctxt *authctxt) { struct identity *id, *id2, *tmp; struct idlist agent, files, *preferred; struct sshkey *key; int agent_fd = -1, i, r, found; size_t j; struct ssh_identitylist *idlist; TAILQ_INIT(&agent); /* keys from the agent */ TAILQ_INIT(&files); /* keys from the config file */ preferred = &authctxt->keys; TAILQ_INIT(preferred); /* preferred order of keys */ /* list of keys stored in the filesystem and PKCS#11 */ for (i = 0; i < options.num_identity_files; i++) { key = options.identity_keys[i]; if (key && key->type == KEY_RSA1) continue; if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) continue; options.identity_keys[i] = NULL; id = xcalloc(1, sizeof(*id)); id->agent_fd = -1; id->key = key; id->filename = xstrdup(options.identity_files[i]); id->userprovided = options.identity_file_userprovided[i]; TAILQ_INSERT_TAIL(&files, id, next); } /* Prefer PKCS11 keys that are explicitly listed */ TAILQ_FOREACH_SAFE(id, &files, next, tmp) { if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0) continue; found = 0; TAILQ_FOREACH(id2, &files, next) { if (id2->key == NULL || (id2->key->flags & SSHKEY_FLAG_EXT) == 0) continue; if (sshkey_equal(id->key, id2->key)) { TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); found = 1; break; } } /* If IdentitiesOnly set and key not found then don't use it */ if (!found && options.identities_only) { TAILQ_REMOVE(&files, id, next); explicit_bzero(id, sizeof(*id)); free(id); } } /* list of certificates specified by user */ for (i = 0; i < options.num_certificate_files; i++) { key = options.certificates[i]; if (!key_is_cert(key) || key->cert == NULL || key->cert->type != SSH2_CERT_TYPE_USER) continue; id = xcalloc(1, sizeof(*id)); id->agent_fd = -1; id->key = key; id->filename = xstrdup(options.certificate_files[i]); id->userprovided = options.certificate_file_userprovided[i]; TAILQ_INSERT_TAIL(preferred, id, next); } /* list of keys supported by the agent */ if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) { if (r != SSH_ERR_AGENT_NO_IDENTITIES) debug("%s: ssh_fetch_identitylist: %s", __func__, ssh_err(r)); close(agent_fd); } else { for (j = 0; j < idlist->nkeys; j++) { found = 0; TAILQ_FOREACH(id, &files, next) { /* * agent keys from the config file are * preferred */ if (sshkey_equal(idlist->keys[j], id->key)) { TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); id->agent_fd = agent_fd; found = 1; break; } } if (!found && !options.identities_only) { id = xcalloc(1, sizeof(*id)); /* XXX "steals" key/comment from idlist */ id->key = idlist->keys[j]; id->filename = idlist->comments[j]; idlist->keys[j] = NULL; idlist->comments[j] = NULL; id->agent_fd = agent_fd; TAILQ_INSERT_TAIL(&agent, id, next); } } ssh_free_identitylist(idlist); /* append remaining agent keys */ for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) { TAILQ_REMOVE(&agent, id, next); TAILQ_INSERT_TAIL(preferred, id, next); } authctxt->agent_fd = agent_fd; } /* append remaining keys from the config file */ for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); } /* finally, filter by PubkeyAcceptedKeyTypes */ TAILQ_FOREACH_SAFE(id, preferred, next, id2) { if (id->key != NULL && match_pattern_list(sshkey_ssh_name(id->key), options.pubkey_key_types, 0) != 1) { debug("Skipping %s key %s - " "not in PubkeyAcceptedKeyTypes", sshkey_ssh_name(id->key), id->filename); TAILQ_REMOVE(preferred, id, next); sshkey_free(id->key); free(id->filename); memset(id, 0, sizeof(*id)); continue; } debug2("key: %s (%p)%s%s", id->filename, id->key, id->userprovided ? ", explicit" : "", id->agent_fd != -1 ? ", agent" : ""); } } static void pubkey_cleanup(Authctxt *authctxt) { Identity *id; if (authctxt->agent_fd != -1) ssh_close_authentication_socket(authctxt->agent_fd); for (id = TAILQ_FIRST(&authctxt->keys); id; id = TAILQ_FIRST(&authctxt->keys)) { TAILQ_REMOVE(&authctxt->keys, id, next); sshkey_free(id->key); free(id->filename); free(id); } } static int try_identity(Identity *id) { if (!id->key) return (0); if (key_type_plain(id->key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { debug("Skipped %s key %s for RSA/MD5 server", key_type(id->key), id->filename); return (0); } return (id->key->type != KEY_RSA1); } int userauth_pubkey(Authctxt *authctxt) { Identity *id; int sent = 0; while ((id = TAILQ_FIRST(&authctxt->keys))) { if (id->tried++) return (0); /* move key to the end of the queue */ TAILQ_REMOVE(&authctxt->keys, id, next); TAILQ_INSERT_TAIL(&authctxt->keys, id, next); /* * send a test message if we have the public key. for * encrypted keys we cannot do this and have to load the * private key instead */ if (id->key != NULL) { if (try_identity(id)) { debug("Offering %s public key: %s", key_type(id->key), id->filename); sent = send_pubkey_test(authctxt, id); } } else { debug("Trying private key: %s", id->filename); id->key = load_identity_file(id); if (id->key != NULL) { if (try_identity(id)) { id->isprivate = 1; sent = sign_and_send_pubkey( authctxt, id); } key_free(id->key); id->key = NULL; } } if (sent) return (sent); } return (0); } /* * Send userauth request message specifying keyboard-interactive method. */ int userauth_kbdint(Authctxt *authctxt) { static int attempt = 0; if (attempt++ >= options.number_of_password_prompts) return 0; /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ if (attempt > 1 && !authctxt->info_req_seen) { debug3("userauth_kbdint: disable: no info_req_seen"); dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); return 0; } debug2("userauth_kbdint"); packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_cstring(""); /* lang */ packet_put_cstring(options.kbd_interactive_devices ? options.kbd_interactive_devices : ""); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); return 1; } /* * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */ int input_userauth_info_req(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; char *name, *inst, *lang, *prompt, *response; u_int num_prompts, i; int echo = 0; debug2("input_userauth_info_req"); if (authctxt == NULL) fatal("input_userauth_info_req: no authentication context"); authctxt->info_req_seen = 1; name = packet_get_string(NULL); inst = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(name) > 0) logit("%s", name); if (strlen(inst) > 0) logit("%s", inst); free(name); free(inst); free(lang); num_prompts = packet_get_int(); /* * Begin to build info response packet based on prompts requested. * We commit to providing the correct number of responses, so if * further on we run into a problem that prevents this, we have to * be sure and clean this up and send a correct error response. */ packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); packet_put_int(num_prompts); debug2("input_userauth_info_req: num_prompts %d", num_prompts); for (i = 0; i < num_prompts; i++) { prompt = packet_get_string(NULL); echo = packet_get_char(); response = read_passphrase(prompt, echo ? RP_ECHO : 0); packet_put_cstring(response); explicit_bzero(response, strlen(response)); free(response); free(prompt); } packet_check_eom(); /* done with parsing incoming message. */ packet_add_padding(64); packet_send(); return 0; } static int ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen) { struct sshbuf *b; struct stat st; pid_t pid; int i, r, to[2], from[2], status, sock = packet_get_connection_in(); u_char rversion = 0, version = 2; void (*osigchld)(int); *sigp = NULL; *lenp = 0; if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { error("%s: not installed: %s", __func__, strerror(errno)); return -1; } if (fflush(stdout) != 0) { error("%s: fflush: %s", __func__, strerror(errno)); return -1; } if (pipe(to) < 0) { error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if (pipe(from) < 0) { error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if ((pid = fork()) < 0) { error("%s: fork: %s", __func__, strerror(errno)); return -1; } osigchld = signal(SIGCHLD, SIG_DFL); if (pid == 0) { /* keep the socket on exec */ fcntl(sock, F_SETFD, 0); permanently_drop_suid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) fatal("%s: dup2: %s", __func__, strerror(errno)); close(to[1]); if (dup2(to[0], STDIN_FILENO) < 0) fatal("%s: dup2: %s", __func__, strerror(errno)); close(from[1]); close(to[0]); /* Close everything but stdio and the socket */ for (i = STDERR_FILENO + 1; i < sock; i++) close(i); closefrom(sock + 1); debug3("%s: [child] pid=%ld, exec %s", __func__, (long)getpid(), _PATH_SSH_KEY_SIGN); execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *)NULL); fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, strerror(errno)); } close(from[1]); close(to[0]); if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* send # of sock, data to be signed */ if ((r = sshbuf_put_u32(b, sock) != 0) || (r = sshbuf_put_string(b, data, datalen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (ssh_msg_send(to[1], version, b) == -1) fatal("%s: couldn't send request", __func__); sshbuf_reset(b); r = ssh_msg_recv(from[0], b); close(from[0]); close(to[1]); if (r < 0) { error("%s: no reply", __func__); goto fail; } errno = 0; while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { error("%s: waitpid %ld: %s", __func__, (long)pid, strerror(errno)); goto fail; } } if (!WIFEXITED(status)) { error("%s: exited abnormally", __func__); goto fail; } if (WEXITSTATUS(status) != 0) { error("%s: exited with status %d", __func__, WEXITSTATUS(status)); goto fail; } if ((r = sshbuf_get_u8(b, &rversion)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); goto fail; } if (rversion != version) { error("%s: bad version", __func__); goto fail; } if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); fail: signal(SIGCHLD, osigchld); sshbuf_free(b); return -1; } signal(SIGCHLD, osigchld); sshbuf_free(b); return 0; } int userauth_hostbased(Authctxt *authctxt) { struct ssh *ssh = active_state; struct sshkey *private = NULL; struct sshbuf *b = NULL; const char *service; u_char *sig = NULL, *keyblob = NULL; char *fp = NULL, *chost = NULL, *lname = NULL; size_t siglen = 0, keylen = 0; int i, r, success = 0; if (authctxt->ktypes == NULL) { authctxt->oktypes = xstrdup(options.hostbased_key_types); authctxt->ktypes = authctxt->oktypes; } /* * Work through each listed type pattern in HostbasedKeyTypes, * trying each hostkey that matches the type in turn. */ for (;;) { if (authctxt->active_ktype == NULL) authctxt->active_ktype = strsep(&authctxt->ktypes, ","); if (authctxt->active_ktype == NULL || *authctxt->active_ktype == '\0') break; debug3("%s: trying key type %s", __func__, authctxt->active_ktype); /* check for a useful key */ private = NULL; for (i = 0; i < authctxt->sensitive->nkeys; i++) { if (authctxt->sensitive->keys[i] == NULL || authctxt->sensitive->keys[i]->type == KEY_RSA1 || authctxt->sensitive->keys[i]->type == KEY_UNSPEC) continue; if (match_pattern_list( sshkey_ssh_name(authctxt->sensitive->keys[i]), authctxt->active_ktype, 0) != 1) continue; /* we take and free the key */ private = authctxt->sensitive->keys[i]; authctxt->sensitive->keys[i] = NULL; break; } /* Found one */ if (private != NULL) break; /* No more keys of this type; advance */ authctxt->active_ktype = NULL; } if (private == NULL) { free(authctxt->oktypes); authctxt->oktypes = authctxt->ktypes = NULL; authctxt->active_ktype = NULL; debug("No more client hostkeys for hostbased authentication."); goto out; } if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; } debug("%s: trying hostkey %s %s", __func__, sshkey_ssh_name(private), fp); /* figure out a name for the client host */ if ((lname = get_local_name(packet_get_connection_in())) == NULL) { error("%s: cannot get local ipaddr/name", __func__); goto out; } /* XXX sshbuf_put_stringf? */ xasprintf(&chost, "%s.", lname); debug2("%s: chost %s", __func__, chost); service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; /* construct data */ if ((b = sshbuf_new()) == NULL) { error("%s: sshbuf_new failed", __func__); goto out; } if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) { error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); goto out; } if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || (r = sshbuf_put_cstring(b, service)) != 0 || (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 || (r = sshbuf_put_string(b, keyblob, keylen)) != 0 || (r = sshbuf_put_cstring(b, chost)) != 0 || (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); goto out; } #ifdef DEBUG_PK sshbuf_dump(b, stderr); #endif if (authctxt->sensitive->external_keysign) r = ssh_keysign(private, &sig, &siglen, sshbuf_ptr(b), sshbuf_len(b)); else if ((r = sshkey_sign(private, &sig, &siglen, sshbuf_ptr(b), sshbuf_len(b), NULL, datafellows)) != 0) debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); if (r != 0) { error("sign using hostkey %s %s failed", sshkey_ssh_name(private), fp); goto out; } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 || (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 || (r = sshpkt_put_cstring(ssh, chost)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 || (r = sshpkt_put_string(ssh, sig, siglen)) != 0 || (r = sshpkt_send(ssh)) != 0) { error("%s: packet error: %s", __func__, ssh_err(r)); goto out; } success = 1; out: if (sig != NULL) { explicit_bzero(sig, siglen); free(sig); } free(keyblob); free(lname); free(fp); free(chost); sshkey_free(private); sshbuf_free(b); return success; } /* find auth method */ /* * given auth method name, if configurable options permit this method fill * in auth_ident field and return true, otherwise return false. */ static int authmethod_is_enabled(Authmethod *method) { if (method == NULL) return 0; /* return false if options indicate this method is disabled */ if (method->enabled == NULL || *method->enabled == 0) return 0; /* return false if batch mode is enabled but method needs interactive mode */ if (method->batch_flag != NULL && *method->batch_flag != 0) return 0; return 1; } static Authmethod * authmethod_lookup(const char *name) { Authmethod *method = NULL; if (name != NULL) for (method = authmethods; method->name != NULL; method++) if (strcmp(name, method->name) == 0) return method; debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); return NULL; } /* XXX internal state */ static Authmethod *current = NULL; static char *supported = NULL; static char *preferred = NULL; /* * Given the authentication method list sent by the server, return the * next method we should try. If the server initially sends a nil list, * use a built-in default list. */ static Authmethod * authmethod_get(char *authlist) { char *name = NULL; u_int next; /* Use a suitable default if we're passed a nil list. */ if (authlist == NULL || strlen(authlist) == 0) authlist = options.preferred_authentications; if (supported == NULL || strcmp(authlist, supported) != 0) { debug3("start over, passed a different list %s", authlist); free(supported); supported = xstrdup(authlist); preferred = options.preferred_authentications; debug3("preferred %s", preferred); current = NULL; } else if (current != NULL && authmethod_is_enabled(current)) return current; for (;;) { if ((name = match_list(preferred, supported, &next)) == NULL) { debug("No more authentication methods to try."); current = NULL; return NULL; } preferred += next; debug3("authmethod_lookup %s", name); debug3("remaining preferred: %s", preferred); if ((current = authmethod_lookup(name)) != NULL && authmethod_is_enabled(current)) { debug3("authmethod_is_enabled %s", name); debug("Next authentication method: %s", name); free(name); return current; } free(name); } } static char * authmethods_get(void) { Authmethod *method = NULL; Buffer b; char *list; buffer_init(&b); for (method = authmethods; method->name != NULL; method++) { if (authmethod_is_enabled(method)) { if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); buffer_append(&b, method->name, strlen(method->name)); } } buffer_append(&b, "\0", 1); list = xstrdup(buffer_ptr(&b)); buffer_free(&b); return list; } openssh-7.2p2/sshd.8010064400017500001750000000771041267006270000125150ustar00djmdjm.\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $OpenBSD: sshd.8,v 1.284 2016/02/17 07:38:19 jmc Exp $ .Dd $Mdocdate: February 17 2016 $ .Dt SSHD 8 .Os .Sh NAME .Nm sshd .Nd OpenSSH SSH daemon .Sh SYNOPSIS .Nm sshd .Bk -words .Op Fl 46DdeiqTt .Op Fl b Ar bits .Op Fl C Ar connection_spec .Op Fl c Ar host_certificate_file .Op Fl E Ar log_file .Op Fl f Ar config_file .Op Fl g Ar login_grace_time .Op Fl h Ar host_key_file .Op Fl k Ar key_gen_time .Op Fl o Ar option .Op Fl p Ar port .Op Fl u Ar len .Ek .Sh DESCRIPTION .Nm (OpenSSH Daemon) is the daemon program for .Xr ssh 1 . Together these programs replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure network. .Pp .Nm listens for connections from clients. It is normally started at boot from .Pa /etc/rc . It forks a new daemon for each incoming connection. The forked daemons handle key exchange, encryption, authentication, command execution, and data exchange. .Pp .Nm can be configured using command-line options or a configuration file (by default .Xr sshd_config 5 ) ; command-line options override values specified in the configuration file. .Nm rereads its configuration file when it receives a hangup signal, .Dv SIGHUP , by executing itself with the name and options it was started with, e.g.\& .Pa /usr/sbin/sshd . .Pp The options are as follows: .Bl -tag -width Ds .It Fl 4 Forces .Nm to use IPv4 addresses only. .It Fl 6 Forces .Nm to use IPv6 addresses only. .It Fl b Ar bits Specifies the number of bits in the ephemeral protocol version 1 server key (default 1024). .It Fl C Ar connection_spec Specify the connection parameters to use for the .Fl T extended test mode. If provided, any .Cm Match directives in the configuration file that would apply to the specified user, host, and address will be set before the configuration is written to standard output. The connection parameters are supplied as keyword=value pairs. The keywords are .Dq user , .Dq host , .Dq laddr , .Dq lport , and .Dq addr . All are required and may be supplied in any order, either with multiple .Fl C options or as a comma-separated list. .It Fl c Ar host_certificate_file Specifies a path to a certificate file to identify .Nm during key exchange. The certificate file must match a host key file specified using the .Fl h option or the .Cm HostKey configuration directive. .It Fl D When this option is specified, .Nm will not detach and does not become a daemon. This allows easy monitoring of .Nm sshd . .It Fl d Debug mode. The server sends verbose debug output to standard error, and does not put itself in the background. The server also will not fork and will only process one connection. This option is only intended for debugging for the server. Multiple .Fl d options increase the debugging level. Maximum is 3. .It Fl E Ar log_file Append debug logs to .Ar log_file instead of the system log. .It Fl e Write debug logs to standard error instead of the system log. .It Fl f Ar config_file Specifies the name of the configuration file. The default is .Pa /etc/ssh/sshd_config . .Nm refuses to start if there is no configuration file. .It Fl g Ar login_grace_time Gives the grace time for clients to authenticate themselves (default 120 seconds). If the client fails to authenticate the user within this many seconds, the server disconnects and exits. A value of zero indicates no limit. .It Fl h Ar host_key_file Specifies a file from which a host key is read. This option must be given if .Nm is not run as root (as the normal host key files are normally not readable by anyone but root). The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and .Pa /etc/ssh/ssh_host_dsa_key , .Pa /etc/ssh/ssh_host_ecdsa_key . .Pa /etc/ssh/ssh_host_ed25519_key and .Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. It is possible to have multiple host key files for the different protocol versions and host key algorithms. .It Fl i Specifies that .Nm is being run from .Xr inetd 8 . If SSH protocol 1 is enabled, .Nm should not normally be run from inetd because it needs to generate the server key before it can respond to the client, and this may take some time. Clients may have to wait too long if the key was regenerated every time. .It Fl k Ar key_gen_time Specifies how often the ephemeral protocol version 1 server key is regenerated (default 3600 seconds, or one hour). The motivation for regenerating the key fairly often is that the key is not stored anywhere, and after about an hour it becomes impossible to recover the key for decrypting intercepted communications even if the machine is cracked into or physically seized. A value of zero indicates that the key will never be regenerated. .It Fl o Ar option Can be used to give options in the format used in the configuration file. This is useful for specifying options for which there is no separate command-line flag. For full details of the options, and their values, see .Xr sshd_config 5 . .It Fl p Ar port Specifies the port on which the server listens for connections (default 22). Multiple port options are permitted. Ports specified in the configuration file with the .Cm Port option are ignored when a command-line port is specified. Ports specified using the .Cm ListenAddress option override command-line ports. .It Fl q Quiet mode. Nothing is sent to the system log. Normally the beginning, authentication, and termination of each connection is logged. .It Fl T Extended test mode. Check the validity of the configuration file, output the effective configuration to stdout and then exit. Optionally, .Cm Match rules may be applied by specifying the connection parameters using one or more .Fl C options. .It Fl t Test mode. Only check the validity of the configuration file and sanity of the keys. This is useful for updating .Nm reliably as configuration options may change. .It Fl u Ar len This option is used to specify the size of the field in the .Li utmp structure that holds the remote host name. If the resolved host name is longer than .Ar len , the dotted decimal value will be used instead. This allows hosts with very long host names that overflow this field to still be uniquely identified. Specifying .Fl u0 indicates that only dotted decimal addresses should be put into the .Pa utmp file. .Fl u0 may also be used to prevent .Nm from making DNS requests unless the authentication mechanism or configuration requires it. Authentication mechanisms that may require DNS include .Cm RhostsRSAAuthentication , .Cm HostbasedAuthentication , and using a .Cm from="pattern-list" option in a key file. Configuration options that require DNS include using a USER@HOST pattern in .Cm AllowUsers or .Cm DenyUsers . .El .Sh AUTHENTICATION The OpenSSH SSH daemon supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the .Cm Protocol option in .Xr sshd_config 5 . Protocol 1 should not be used and is only offered to support legacy devices. .Pp Each host has a host-specific key, used to identify the host. Partial forward security for protocol 1 is provided through an additional server key, normally 1024 bits, generated when the server starts. This key is normally regenerated every hour if it has been used, and is never stored on disk. Whenever a client connects, the daemon responds with its public host and server keys. The client compares the RSA host key against its own database to verify that it has not changed. The client then generates a 256-bit random number. It encrypts this random number using both the host key and the server key, and sends the encrypted number to the server. Both sides then use this random number as a session key which is used to encrypt all further communications in the session. The rest of the session is encrypted using a conventional cipher, currently Blowfish or 3DES, with 3DES being used by default. The client selects the encryption algorithm to use from those offered by the server. .Pp For protocol 2, forward security is provided through a Diffie-Hellman key agreement. This key agreement results in a shared session key. The rest of the session is encrypted using a symmetric cipher, currently 128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES. The client selects the encryption algorithm to use from those offered by the server. Additionally, session integrity is provided through a cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64, umac-128, hmac-ripemd160, hmac-sha2-256 or hmac-sha2-512). .Pp Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using host-based authentication, public key authentication, challenge-response authentication, or password authentication. .Pp Regardless of the authentication type, the account is checked to ensure that it is accessible. An account is not accessible if it is locked, listed in .Cm DenyUsers or its group is listed in .Cm DenyGroups \&. The definition of a locked account is system dependant. Some platforms have their own account database (eg AIX) and some modify the passwd field ( .Ql \&*LK\&* on Solaris and UnixWare, .Ql \&* on HP-UX, containing .Ql Nologin on Tru64, a leading .Ql \&*LOCKED\&* on FreeBSD and a leading .Ql \&! on most Linuxes). If there is a requirement to disable password authentication for the account while allowing still public-key, then the passwd field should be set to something other than these values (eg .Ql NP or .Ql \&*NP\&* ). .Pp If the client successfully authenticates itself, a dialog for preparing the session is entered. At this time the client may request things like allocating a pseudo-tty, forwarding X11 connections, forwarding TCP connections, or forwarding the authentication agent connection over the secure channel. .Pp After this, the client either requests a shell or execution of a command. The sides then enter session mode. In this mode, either side may send data at any time, and such data is forwarded to/from the shell or command on the server side, and the user terminal in the client side. .Pp When the user program terminates and all forwarded X11 and other connections have been closed, the server sends command exit status to the client, and both sides exit. .Sh LOGIN PROCESS When a user successfully logs in, .Nm does the following: .Bl -enum -offset indent .It If the login is on a tty, and no command has been specified, prints last login time and .Pa /etc/motd (unless prevented in the configuration file or by .Pa ~/.hushlogin ; see the .Sx FILES section). .It If the login is on a tty, records login time. .It Checks .Pa /etc/nologin ; if it exists, prints contents and quits (unless root). .It Changes to run with normal user privileges. .It Sets up basic environment. .It Reads the file .Pa ~/.ssh/environment , if it exists, and users are allowed to change their environment. See the .Cm PermitUserEnvironment option in .Xr sshd_config 5 . .It Changes to user's home directory. .It If .Pa ~/.ssh/rc exists and the .Xr sshd_config 5 .Cm PermitUserRC option is set, runs it; else if .Pa /etc/ssh/sshrc exists, runs it; otherwise runs xauth. The .Dq rc files are given the X11 authentication protocol and cookie in standard input. See .Sx SSHRC , below. .It Runs user's shell or command. All commands are run under the user's login shell as specified in the system password database. .El .Sh SSHRC If the file .Pa ~/.ssh/rc exists, .Xr sh 1 runs it after reading the environment files but before starting the user's shell or command. It must not produce any output on stdout; stderr must be used instead. If X11 forwarding is in use, it will receive the "proto cookie" pair in its standard input (and .Ev DISPLAY in its environment). The script must call .Xr xauth 1 because .Nm will not run xauth automatically to add X11 cookies. .Pp The primary purpose of this file is to run any initialization routines which may be needed before the user's home directory becomes accessible; AFS is a particular example of such an environment. .Pp This file will probably contain some initialization code followed by something similar to: .Bd -literal -offset 3n if read proto cookie && [ -n "$DISPLAY" ]; then if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then # X11UseLocalhost=yes echo add unix:`echo $DISPLAY | cut -c11-` $proto $cookie else # X11UseLocalhost=no echo add $DISPLAY $proto $cookie fi | xauth -q - fi .Ed .Pp If this file does not exist, .Pa /etc/ssh/sshrc is run, and if that does not exist either, xauth is used to add the cookie. .Sh AUTHORIZED_KEYS FILE FORMAT .Cm AuthorizedKeysFile specifies the files containing public keys for public key authentication; if this option is not specified, the default is .Pa ~/.ssh/authorized_keys and .Pa ~/.ssh/authorized_keys2 . Each line of the file contains one key (empty lines and lines starting with a .Ql # are ignored as comments). Protocol 1 public keys consist of the following space-separated fields: options, bits, exponent, modulus, comment. Protocol 2 public key consist of: options, keytype, base64-encoded key, comment. The options field is optional; its presence is determined by whether the line starts with a number or not (the options field never starts with a number). The bits, exponent, modulus, and comment fields give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). For protocol version 2 the keytype is .Dq ecdsa-sha2-nistp256 , .Dq ecdsa-sha2-nistp384 , .Dq ecdsa-sha2-nistp521 , .Dq ssh-ed25519 , .Dq ssh-dss or .Dq ssh-rsa . .Pp Note that lines in this file are usually several hundred bytes long (because of the size of the public key encoding) up to a limit of 8 kilobytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16 kilobits. You don't want to type them in; instead, copy the .Pa identity.pub , .Pa id_dsa.pub , .Pa id_ecdsa.pub , .Pa id_ed25519.pub , or the .Pa id_rsa.pub file and edit it. .Pp .Nm enforces a minimum RSA key modulus size for protocol 1 and protocol 2 keys of 768 bits. .Pp The options (if present) consist of comma-separated option specifications. No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds .It Cm agent-forwarding Enable authentication agent forwarding previously disabled by the .Cm restrict option. .It Cm cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user authentication. .Pp Certificates may encode access restrictions similar to these key options. If both certificate restrictions and key options are present, the most restrictive union of the two is applied. .It Cm command="command" Specifies that the command is executed whenever this key is used for authentication. The command supplied by the user (if any) is ignored. The command is run on a pty if the client requests a pty; otherwise it is run without a tty. If an 8-bit clean channel is required, one must not request a pty or should specify .Cm no-pty . A quote may be included in the command by quoting it with a backslash. This option might be useful to restrict certain public keys to perform just a specific operation. An example might be a key that permits remote backups but nothing else. Note that the client may specify TCP and/or X11 forwarding unless they are explicitly prohibited. The command originally supplied by the client is available in the .Ev SSH_ORIGINAL_COMMAND environment variable. Note that this option applies to shell, command or subsystem execution. Also note that this command may be superseded by either a .Xr sshd_config 5 .Cm ForceCommand directive or a command embedded in a certificate. .It Cm environment="NAME=value" Specifies that the string is to be added to the environment when logging in using this key. Environment variables set this way override other default environment values. Multiple options of this type are permitted. Environment processing is disabled by default and is controlled via the .Cm PermitUserEnvironment option. This option is automatically disabled if .Cm UseLogin is enabled. .It Cm from="pattern-list" Specifies that in addition to public key authentication, either the canonical name of the remote host or its IP address must be present in the comma-separated list of patterns. See PATTERNS in .Xr ssh_config 5 for more information on patterns. .Pp In addition to the wildcard matching that may be applied to hostnames or addresses, a .Cm from stanza may match IP addresses using CIDR address/masklen notation. .Pp The purpose of this option is to optionally increase security: public key authentication by itself does not trust the network or name servers or anything (but the key); however, if somebody somehow steals the key, the key permits an intruder to log in from anywhere in the world. This additional option makes using a stolen key more difficult (name servers and/or routers would have to be compromised in addition to just the key). .It Cm no-agent-forwarding Forbids authentication agent forwarding when this key is used for authentication. .It Cm no-port-forwarding Forbids TCP forwarding when this key is used for authentication. Any port forward requests by the client will return an error. This might be used, e.g. in connection with the .Cm command option. .It Cm no-pty Prevents tty allocation (a request to allocate a pty will fail). .It Cm no-user-rc Disables execution of .Pa ~/.ssh/rc . .It Cm no-X11-forwarding Forbids X11 forwarding when this key is used for authentication. Any X11 forward requests by the client will return an error. .It Cm permitopen="host:port" Limit local port forwarding with .Xr ssh 1 .Fl L such that it may only connect to the specified host and port. IPv6 addresses can be specified by enclosing the address in square brackets. Multiple .Cm permitopen options may be applied separated by commas. No pattern matching is performed on the specified hostnames, they must be literal domains or addresses. A port specification of .Cm * matches any port. .It Cm port-forwarding Enable port forwarding previously disabled by the .Cm restrict .It Cm principals="principals" On a .Cm cert-authority line, specifies allowed principals for certificate authentication as a comma-separated list. At least one name from the list must appear in the certificate's list of principals for the certificate to be accepted. This option is ignored for keys that are not marked as trusted certificate signers using the .Cm cert-authority option. .It Cm pty Permits tty allocation previously disabled by the .Cm restrict option. .It Cm restrict Enable all restrictions, i.e. disable port, agent and X11 forwarding, as well as disabling PTY allocation and execution of .Pa ~/.ssh/rc . If any future restriction capabilities are added to authorized_keys files they will be included in this set. .It Cm tunnel="n" Force a .Xr tun 4 device on the server. Without this option, the next available device will be used if the client requests a tunnel. .It Cm user-rc Enables execution of .Pa ~/.ssh/rc previously disabled by the .Cm restrict option. .It Cm X11-forwarding Permits X11 forwarding previously disabled by the .Cm restrict option. .El .Pp An example authorized_keys file: .Bd -literal -offset 3n # Comments allowed at start of line ssh-rsa AAAAB3Nza...LiPk== user@example.net from="*.sales.example.net,!pc.sales.example.net" ssh-rsa AAAAB2...19Q== john@example.net command="dump /home",no-pty,no-port-forwarding ssh-dss AAAAC3...51R== example.net permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss AAAAB5...21S== tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== user@example.net restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5== user@example.net .Ed .Sh SSH_KNOWN_HOSTS FILE FORMAT The .Pa /etc/ssh/ssh_known_hosts and .Pa ~/.ssh/known_hosts files contain host public keys for all known hosts. The global file should be prepared by the administrator (optional), and the per-user file is maintained automatically: whenever the user connects from an unknown host, its key is added to the per-user file. .Pp Each line in these files contains the following fields: markers (optional), hostnames, bits, exponent, modulus, comment. The fields are separated by spaces. .Pp The marker is optional, but if it is present then it must be one of .Dq @cert-authority , to indicate that the line contains a certification authority (CA) key, or .Dq @revoked , to indicate that the key contained on the line is revoked and must not ever be accepted. Only one marker should be used on a key line. .Pp Hostnames is a comma-separated list of patterns .Pf ( Ql * and .Ql \&? act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name (when authenticating a server). A pattern may also be preceded by .Ql \&! to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. A hostname or address may optionally be enclosed within .Ql \&[ and .Ql \&] brackets then followed by .Ql \&: and a non-standard port number. .Pp Alternately, hostnames may be stored in a hashed form which hides host names and addresses should the file's contents be disclosed. Hashed hostnames start with a .Ql | character. Only one hashed hostname may appear on a single line and none of the above negation or wildcard operators may be applied. .Pp Bits, exponent, and modulus are taken directly from the RSA host key; they can be obtained, for example, from .Pa /etc/ssh/ssh_host_key.pub . The optional comment field continues to the end of the line, and is not used. .Pp Lines starting with .Ql # and empty lines are ignored as comments. .Pp When performing host authentication, authentication is accepted if any matching line has the proper key; either one that matches exactly or, if the server has presented a certificate for authentication, the key of the certification authority that signed the certificate. For a key to be trusted as a certification authority, it must use the .Dq @cert-authority marker described above. .Pp The known hosts file also provides a facility to mark keys as revoked, for example when it is known that the associated private key has been stolen. Revoked keys are specified by including the .Dq @revoked marker at the beginning of the key line, and are never accepted for authentication or as certification authorities, but instead will produce a warning from .Xr ssh 1 when they are encountered. .Pp It is permissible (but not recommended) to have several lines or different host keys for the same names. This will inevitably happen when short forms of host names from different domains are put in the file. It is possible that the files contain conflicting information; authentication is accepted if valid information can be found from either file. .Pp Note that the lines in these files are typically hundreds of characters long, and you definitely don't want to type in the host keys by hand. Rather, generate them by a script, .Xr ssh-keyscan 1 or by taking .Pa /etc/ssh/ssh_host_key.pub and adding the host names at the front. .Xr ssh-keygen 1 also offers some basic automated editing for .Pa ~/.ssh/known_hosts including removing hosts matching a host name and converting all host names to their hashed representations. .Pp An example ssh_known_hosts file: .Bd -literal -offset 3n # Comments allowed at start of line closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....= # A hashed hostname |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa AAAA1234.....= # A revoked key @revoked * ssh-rsa AAAAB5W... # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... .Ed .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin This file is used to suppress printing the last login time and .Pa /etc/motd , if .Cm PrintLastLog and .Cm PrintMotd , respectively, are enabled. It does not suppress printing of the banner specified by .Cm Banner . .Pp .It Pa ~/.rhosts This file is used for host-based authentication (see .Xr ssh 1 for more information). On some machines this file may need to be world-readable if the user's home directory is on an NFS partition, because .Nm reads it as root. Additionally, this file must be owned by the user, and must not have write permissions for anyone else. The recommended permission for most machines is read/write for the user, and not accessible by others. .Pp .It Pa ~/.shosts This file is used in exactly the same way as .Pa .rhosts , but allows host-based authentication without permitting login with rlogin/rsh. .Pp .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. .Pp If this file, the .Pa ~/.ssh directory, or the user's home directory are writable by other users, then the file could be modified or replaced by unauthorized users. In this case, .Nm will not allow it to be used unless the .Cm StrictModes option has been set to .Dq no . .Pp .It Pa ~/.ssh/environment This file is read into the environment at login (if it exists). It can only contain empty lines, comment lines (that start with .Ql # ) , and assignment lines of the form name=value. The file should be writable only by the user; it need not be readable by anyone else. Environment processing is disabled by default and is controlled via the .Cm PermitUserEnvironment option. .Pp .It Pa ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. The format of this file is described above. This file should be writable only by root/the owner and can, but need not be, world-readable. .Pp .It Pa ~/.ssh/rc Contains initialization routines to be run before the user's home directory becomes accessible. This file should be writable only by the user, and need not be readable by anyone else. .Pp .It Pa /etc/hosts.equiv This file is for host-based authentication (see .Xr ssh 1 ) . It should only be writable by root. .Pp .It Pa /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange" key exchange method. The file format is described in .Xr moduli 5 . If no usable groups are found in this file then fixed internal groups will be used. .Pp .It Pa /etc/motd See .Xr motd 5 . .Pp .It Pa /etc/nologin If this file exists, .Nm refuses to let anyone except root log in. The contents of the file are displayed to anyone trying to log in, and non-root connections are refused. The file should be world-readable. .Pp .It Pa /etc/shosts.equiv This file is used in exactly the same way as .Pa hosts.equiv , but allows host-based authentication without permitting login with rlogin/rsh. .Pp .It Pa /etc/ssh/ssh_host_key .It Pa /etc/ssh/ssh_host_dsa_key .It Pa /etc/ssh/ssh_host_ecdsa_key .It Pa /etc/ssh/ssh_host_ed25519_key .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys. These files should only be owned by root, readable only by root, and not accessible to others. Note that .Nm does not start if these files are group/world-accessible. .Pp .It Pa /etc/ssh/ssh_host_key.pub .It Pa /etc/ssh/ssh_host_dsa_key.pub .It Pa /etc/ssh/ssh_host_ecdsa_key.pub .It Pa /etc/ssh/ssh_host_ed25519_key.pub .It Pa /etc/ssh/ssh_host_rsa_key.pub These files contain the public parts of the host keys. These files should be world-readable but writable only by root. Their contents should match the respective private parts. These files are not really used for anything; they are provided for the convenience of the user so their contents can be copied to known hosts files. These files are created using .Xr ssh-keygen 1 . .Pp .It Pa /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the organization. The format of this file is described above. This file should be writable only by root/the owner and should be world-readable. .Pp .It Pa /etc/ssh/sshd_config Contains configuration data for .Nm sshd . The file format and configuration options are described in .Xr sshd_config 5 . .Pp .It Pa /etc/ssh/sshrc Similar to .Pa ~/.ssh/rc , it can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. .Pp .It Pa /var/empty .Xr chroot 2 directory used by .Nm during privilege separation in the pre-authentication phase. The directory should not contain any files and must be owned by root and not group or world-writable. .Pp .It Pa /var/run/sshd.pid Contains the process ID of the .Nm listening for connections (if there are several daemons running concurrently for different ports, this contains the process ID of the one started last). The content of this file is not sensitive; it can be world-readable. .El .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , .Xr ssh-keyscan 1 , .Xr chroot 2 , .Xr login.conf 5 , .Xr moduli 5 , .Xr sshd_config 5 , .Xr inetd 8 , .Xr sftp-server 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. openssh-7.2p2/sshd.c010064400017500001750000002145631267006270000125720ustar00djmdjm/* $OpenBSD: sshd.c,v 1.465 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * This program is the ssh daemon. It listens for connections from clients, * and performs authentication, executes use commands or shell, and forwards * information to/from the application to the user client over an encrypted * connection. This can also handle forwarding of X11, TCP/IP, and * authentication agent connections. * * 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: * Privilege Separation: * * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 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 #include #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include "openbsd-compat/sys-tree.h" #include "openbsd-compat/sys-queue.h" #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #include #include #include #include #include #include #include #include #include #ifdef WITH_OPENSSL #include #include #include #include "openbsd-compat/openssl-compat.h" #endif #ifdef HAVE_SECUREWARE #include #include #endif #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" #include "rsa.h" #include "sshpty.h" #include "packet.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "match.h" #include "servconf.h" #include "uidswap.h" #include "compat.h" #include "cipher.h" #include "digest.h" #include "key.h" #include "kex.h" #include "myproposal.h" #include "authfile.h" #include "pathnames.h" #include "atomicio.h" #include "canohost.h" #include "hostfile.h" #include "auth.h" #include "authfd.h" #include "msg.h" #include "dispatch.h" #include "channels.h" #include "session.h" #include "monitor_mm.h" #include "monitor.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" #ifndef O_NOCTTY #define O_NOCTTY 0 #endif /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) extern char *__progname; /* Server configuration options. */ ServerOptions options; /* Name of the server configuration file. */ char *config_file_name = _PATH_SERVER_CONFIG_FILE; /* * Debug mode flag. This can be set on the command line. If debug * mode is enabled, extra debugging output will be sent to the system * log, the daemon will not go to background, and will exit after processing * the first connection. */ int debug_flag = 0; /* Flag indicating that the daemon should only test the configuration and keys. */ int test_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ int inetd_flag = 0; /* Flag indicating that sshd should not detach and become a daemon. */ int no_daemon_flag = 0; /* debug goes to stderr unless inetd_flag is set */ int log_stderr = 0; /* Saved arguments to main(). */ char **saved_argv; int saved_argc; /* re-exec */ int rexeced_flag = 0; int rexec_flag = 1; int rexec_argc = 0; char **rexec_argv; /* * The sockets that the server is listening; this is used in the SIGHUP * signal handler. */ #define MAX_LISTEN_SOCKS 16 int listen_socks[MAX_LISTEN_SOCKS]; int num_listen_socks = 0; /* * the client's version string, passed by sshd2 in compat mode. if != NULL, * sshd will skip the version-number exchange */ char *client_version_string = NULL; char *server_version_string = NULL; /* Daemon's agent connection */ int auth_sock = -1; int have_agent = 0; /* * Any really sensitive data in the application is contained in this * structure. The idea is that this structure could be locked into memory so * that the pages do not get written into swap. However, there are some * problems. The private key contains BIGNUMs, and we do not (in principle) * have access to the internals of them, and locking just the structure is * not very useful. Currently, memory locking is not implemented. */ struct { Key *server_key; /* ephemeral server key */ Key *ssh1_host_key; /* ssh1 host key */ Key **host_keys; /* all private host keys */ Key **host_pubkeys; /* all public host keys */ Key **host_certificates; /* all public host certificates */ int have_ssh1_key; int have_ssh2_key; u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; } sensitive_data; /* * Flag indicating whether the RSA server key needs to be regenerated. * Is set in the SIGALRM handler and cleared when the key is regenerated. */ static volatile sig_atomic_t key_do_regen = 0; /* This is set to true when a signal is received. */ static volatile sig_atomic_t received_sighup = 0; static volatile sig_atomic_t received_sigterm = 0; /* session identifier, used by RSA-auth */ u_char session_id[16]; /* same for ssh2 */ u_char *session_id2 = NULL; u_int session_id2_len = 0; /* record remote hostname or ip */ u_int utmp_len = HOST_NAME_MAX+1; /* options.max_startup sized array of fd ints */ int *startup_pipes = NULL; int startup_pipe; /* in child */ /* variables used for privilege separation */ int use_privsep = -1; struct monitor *pmonitor = NULL; int privsep_is_preauth = 1; /* global authentication context */ Authctxt *the_authctxt = NULL; /* sshd_config buffer */ Buffer cfg; /* message to be displayed after login */ Buffer loginmsg; /* Unprivileged user */ struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); #ifdef WITH_SSH1 static void do_ssh1_kex(void); #endif static void do_ssh2_kex(void); /* * Close all listening sockets */ static void close_listen_socks(void) { int i; for (i = 0; i < num_listen_socks; i++) close(listen_socks[i]); num_listen_socks = -1; } static void close_startup_pipes(void) { int i; if (startup_pipes) for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1) close(startup_pipes[i]); } /* * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; * the effect is to reread the configuration file (and to regenerate * the server key). */ /*ARGSUSED*/ static void sighup_handler(int sig) { int save_errno = errno; received_sighup = 1; signal(SIGHUP, sighup_handler); errno = save_errno; } /* * Called from the main program after receiving SIGHUP. * Restarts the server. */ static void sighup_restart(void) { logit("Received SIGHUP; restarting."); platform_pre_restart(); close_listen_socks(); close_startup_pipes(); alarm(0); /* alarm timer persists across exec */ signal(SIGHUP, SIG_IGN); /* will be restored after exec */ execv(saved_argv[0], saved_argv); logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno)); exit(1); } /* * Generic signal handler for terminating signals in the master daemon. */ /*ARGSUSED*/ static void sigterm_handler(int sig) { received_sigterm = sig; } /* * SIGCHLD handler. This is called whenever a child dies. This will then * reap any zombies left by exited children. */ /*ARGSUSED*/ static void main_sigchld_handler(int sig) { int save_errno = errno; pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) ; signal(SIGCHLD, main_sigchld_handler); errno = save_errno; } /* * Signal handler for the alarm after the login grace period has expired. */ /*ARGSUSED*/ static void grace_alarm_handler(int sig) { if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0) kill(pmonitor->m_pid, SIGALRM); /* * Try to kill any processes that we have spawned, E.g. authorized * keys command helpers. */ if (getpgid(0) == getpid()) { signal(SIGTERM, SIG_IGN); kill(0, SIGTERM); } /* Log error and exit. */ sigdie("Timeout before authentication for %s", get_remote_ipaddr()); } /* * Signal handler for the key regeneration alarm. Note that this * alarm only occurs in the daemon waiting for connections, and it does not * do anything with the private key or random state before forking. * Thus there should be no concurrency control/asynchronous execution * problems. */ static void generate_ephemeral_server_key(void) { verbose("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "", options.server_key_bits); if (sensitive_data.server_key != NULL) key_free(sensitive_data.server_key); sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits); verbose("RSA key generation complete."); arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); } /*ARGSUSED*/ static void key_regeneration_alarm(int sig) { int save_errno = errno; signal(SIGALRM, SIG_DFL); errno = save_errno; key_do_regen = 1; } static void sshd_exchange_identification(int sock_in, int sock_out) { u_int i; int mismatch; int remote_major, remote_minor; int major, minor; char *s, *newline = "\n"; char buf[256]; /* Must not be larger than remote_version. */ char remote_version[256]; /* Must be at least as big as buf. */ if ((options.protocol & SSH_PROTO_1) && (options.protocol & SSH_PROTO_2)) { major = PROTOCOL_MAJOR_1; minor = 99; } else if (options.protocol & SSH_PROTO_2) { major = PROTOCOL_MAJOR_2; minor = PROTOCOL_MINOR_2; newline = "\r\n"; } else { major = PROTOCOL_MAJOR_1; minor = PROTOCOL_MINOR_1; } xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", major, minor, SSH_VERSION, *options.version_addendum == '\0' ? "" : " ", options.version_addendum, newline); /* Send our protocol version identification. */ if (atomicio(vwrite, sock_out, server_version_string, strlen(server_version_string)) != strlen(server_version_string)) { logit("Could not write ident string to %s", get_remote_ipaddr()); cleanup_exit(255); } /* Read other sides version identification. */ memset(buf, 0, sizeof(buf)); for (i = 0; i < sizeof(buf) - 1; i++) { if (atomicio(read, sock_in, &buf[i], 1) != 1) { logit("Did not receive identification string from %s", get_remote_ipaddr()); cleanup_exit(255); } if (buf[i] == '\r') { buf[i] = 0; /* Kludge for F-Secure Macintosh < 1.0.2 */ if (i == 12 && strncmp(buf, "SSH-1.5-W1.0", 12) == 0) break; continue; } if (buf[i] == '\n') { buf[i] = 0; break; } } buf[sizeof(buf) - 1] = 0; client_version_string = xstrdup(buf); /* * Check that the versions match. In future this might accept * several versions and set appropriate flags to handle them. */ if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) { s = "Protocol mismatch.\n"; (void) atomicio(vwrite, sock_out, s, strlen(s)); logit("Bad protocol version identification '%.100s' " "from %s port %d", client_version_string, get_remote_ipaddr(), get_remote_port()); close(sock_in); close(sock_out); cleanup_exit(255); } debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version); active_state->compat = compat_datafellows(remote_version); if ((datafellows & SSH_BUG_PROBE) != 0) { logit("probed from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); cleanup_exit(255); } if ((datafellows & SSH_BUG_SCANNER) != 0) { logit("scanned from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); cleanup_exit(255); } if ((datafellows & SSH_BUG_RSASIGMD5) != 0) { logit("Client version \"%.100s\" uses unsafe RSA signature " "scheme; disabling use of RSA keys", remote_version); } if ((datafellows & SSH_BUG_DERIVEKEY) != 0) { fatal("Client version \"%.100s\" uses unsafe key agreement; " "refusing connection", remote_version); } mismatch = 0; switch (remote_major) { case 1: if (remote_minor == 99) { if (options.protocol & SSH_PROTO_2) enable_compat20(); else mismatch = 1; break; } if (!(options.protocol & SSH_PROTO_1)) { mismatch = 1; break; } if (remote_minor < 3) { packet_disconnect("Your ssh version is too old and " "is no longer supported. Please install a newer version."); } else if (remote_minor == 3) { /* note that this disables agent-forwarding */ enable_compat13(); } break; case 2: if (options.protocol & SSH_PROTO_2) { enable_compat20(); break; } /* FALLTHROUGH */ default: mismatch = 1; break; } chop(server_version_string); debug("Local version string %.200s", server_version_string); if (mismatch) { s = "Protocol major versions differ.\n"; (void) atomicio(vwrite, sock_out, s, strlen(s)); close(sock_in); close(sock_out); logit("Protocol major versions differ for %s: %.200s vs. %.200s", get_remote_ipaddr(), server_version_string, client_version_string); cleanup_exit(255); } } /* Destroy the host and server keys. They will no longer be needed. */ void destroy_sensitive_data(void) { int i; if (sensitive_data.server_key) { key_free(sensitive_data.server_key); sensitive_data.server_key = NULL; } for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { key_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = NULL; } if (sensitive_data.host_certificates[i]) { key_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } } sensitive_data.ssh1_host_key = NULL; explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); } /* Demote private to public keys for network child */ void demote_sensitive_data(void) { Key *tmp; int i; if (sensitive_data.server_key) { tmp = key_demote(sensitive_data.server_key); key_free(sensitive_data.server_key); sensitive_data.server_key = tmp; } for (i = 0; i < options.num_host_key_files; i++) { if (sensitive_data.host_keys[i]) { tmp = key_demote(sensitive_data.host_keys[i]); key_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; if (tmp->type == KEY_RSA1) sensitive_data.ssh1_host_key = tmp; } /* Certs do not need demotion */ } /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ } static void privsep_preauth_child(void) { u_int32_t rnd[256]; gid_t gidset[1]; /* Enable challenge-response authentication for privilege separation */ privsep_challenge_enable(); #ifdef GSSAPI /* Cache supported mechanism OIDs for later use */ if (options.gss_authentication) ssh_gssapi_prepare_supported_oids(); #endif arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); #ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); if ((RAND_bytes((u_char *)rnd, 1)) != 1) fatal("%s: RAND_bytes failed", __func__); #endif explicit_bzero(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ demote_sensitive_data(); /* Demote the child */ if (getuid() == 0 || geteuid() == 0) { /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, strerror(errno)); if (chdir("/") == -1) fatal("chdir(\"/\"): %s", strerror(errno)); /* Drop our privileges */ debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, (u_int)privsep_pw->pw_gid); gidset[0] = privsep_pw->pw_gid; if (setgroups(1, gidset) < 0) fatal("setgroups: %.100s", strerror(errno)); permanently_set_uid(privsep_pw); } } static int privsep_preauth(Authctxt *authctxt) { int status, r; pid_t pid; struct ssh_sandbox *box = NULL; /* Set up unprivileged child process to deal with network data */ pmonitor = monitor_init(); /* Store a pointer to the kex for later rekeying */ pmonitor->m_pkex = &active_state->kex; if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { debug2("Network child is on pid %ld", (long)pid); pmonitor->m_pid = pid; if (have_agent) { r = ssh_get_authentication_socket(&auth_sock); if (r != 0) { error("Could not get agent socket: %s", ssh_err(r)); have_agent = 0; } } if (box != NULL) ssh_sandbox_parent_preauth(box, pid); monitor_child_preauth(authctxt, pmonitor); /* Sync memory */ monitor_sync(pmonitor); /* Wait for the child's exit status */ while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; pmonitor->m_pid = -1; fatal("%s: waitpid: %s", __func__, strerror(errno)); } privsep_is_preauth = 0; pmonitor->m_pid = -1; if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) fatal("%s: preauth child exited with status %d", __func__, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) fatal("%s: preauth child terminated by signal %d", __func__, WTERMSIG(status)); if (box != NULL) ssh_sandbox_parent_finish(box); return 1; } else { /* child */ close(pmonitor->m_sendfd); close(pmonitor->m_log_recvfd); /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); privsep_preauth_child(); setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); return 0; } } static void privsep_postauth(Authctxt *authctxt) { u_int32_t rnd[256]; #ifdef DISABLE_FD_PASSING if (1) { #else if (authctxt->pw->pw_uid == 0 || options.use_login) { #endif /* File descriptor passing is broken or root login */ use_privsep = 0; goto skip; } /* New socket pair */ monitor_reinit(pmonitor); pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) fatal("fork of unprivileged child failed"); else if (pmonitor->m_pid != 0) { verbose("User child is on pid %ld", (long)pmonitor->m_pid); buffer_clear(&loginmsg); monitor_child_postauth(pmonitor); /* NEVERREACHED */ exit(0); } /* child */ close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; /* Demote the private keys to public keys. */ demote_sensitive_data(); arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); #ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); if ((RAND_bytes((u_char *)rnd, 1)) != 1) fatal("%s: RAND_bytes failed", __func__); #endif explicit_bzero(rnd, sizeof(rnd)); /* Drop privileges */ do_setusercontext(authctxt->pw); skip: /* It is safe now to apply the key state */ monitor_apply_keystate(pmonitor); /* * Tell the packet layer that authentication was successful, since * this information is not part of the key state. */ packet_set_authenticated(); } static char * list_hostkey_types(void) { Buffer b; const char *p; char *ret; int i; Key *key; buffer_init(&b); for (i = 0; i < options.num_host_key_files; i++) { key = sensitive_data.host_keys[i]; if (key == NULL) key = sensitive_data.host_pubkeys[i]; if (key == NULL || key->type == KEY_RSA1) continue; /* Check that the key is accepted in HostkeyAlgorithms */ if (match_pattern_list(sshkey_ssh_name(key), options.hostkeyalgorithms, 0) != 1) { debug3("%s: %s key not permitted by HostkeyAlgorithms", __func__, sshkey_ssh_name(key)); continue; } switch (key->type) { case KEY_RSA: case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); /* for RSA we also support SHA2 signatures */ if (key->type == KEY_RSA) { p = ",rsa-sha2-512,rsa-sha2-256"; buffer_append(&b, p, strlen(p)); } break; } /* If the private key has a cert peer, then list that too */ key = sensitive_data.host_certificates[i]; if (key == NULL) continue; switch (key->type) { case KEY_RSA_CERT: case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_ED25519_CERT: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); break; } } buffer_append(&b, "\0", 1); ret = xstrdup(buffer_ptr(&b)); buffer_free(&b); debug("list_hostkey_types: %s", ret); return ret; } static Key * get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) { int i; Key *key; for (i = 0; i < options.num_host_key_files; i++) { switch (type) { case KEY_RSA_CERT: case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_ED25519_CERT: key = sensitive_data.host_certificates[i]; break; default: key = sensitive_data.host_keys[i]; if (key == NULL && !need_private) key = sensitive_data.host_pubkeys[i]; break; } if (key != NULL && key->type == type && (key->type != KEY_ECDSA || key->ecdsa_nid == nid)) return need_private ? sensitive_data.host_keys[i] : key; } return NULL; } Key * get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) { return get_hostkey_by_type(type, nid, 0, ssh); } Key * get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) { return get_hostkey_by_type(type, nid, 1, ssh); } Key * get_hostkey_by_index(int ind) { if (ind < 0 || ind >= options.num_host_key_files) return (NULL); return (sensitive_data.host_keys[ind]); } Key * get_hostkey_public_by_index(int ind, struct ssh *ssh) { if (ind < 0 || ind >= options.num_host_key_files) return (NULL); return (sensitive_data.host_pubkeys[ind]); } int get_hostkey_index(Key *key, int compare, struct ssh *ssh) { int i; for (i = 0; i < options.num_host_key_files; i++) { if (key_is_cert(key)) { if (key == sensitive_data.host_certificates[i] || (compare && sensitive_data.host_certificates[i] && sshkey_equal(key, sensitive_data.host_certificates[i]))) return (i); } else { if (key == sensitive_data.host_keys[i] || (compare && sensitive_data.host_keys[i] && sshkey_equal(key, sensitive_data.host_keys[i]))) return (i); if (key == sensitive_data.host_pubkeys[i] || (compare && sensitive_data.host_pubkeys[i] && sshkey_equal(key, sensitive_data.host_pubkeys[i]))) return (i); } } return (-1); } /* Inform the client of all hostkeys */ static void notify_hostkeys(struct ssh *ssh) { struct sshbuf *buf; struct sshkey *key; int i, nkeys, r; char *fp; /* Some clients cannot cope with the hostkeys message, skip those. */ if (datafellows & SSH_BUG_HOSTKEYS) return; if ((buf = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); for (i = nkeys = 0; i < options.num_host_key_files; i++) { key = get_hostkey_public_by_index(i, ssh); if (key == NULL || key->type == KEY_UNSPEC || key->type == KEY_RSA1 || sshkey_is_cert(key)) continue; fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); debug3("%s: key %d: %s %s", __func__, i, sshkey_ssh_name(key), fp); free(fp); if (nkeys == 0) { packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("hostkeys-00@openssh.com"); packet_put_char(0); /* want-reply */ } sshbuf_reset(buf); if ((r = sshkey_putb(key, buf)) != 0) fatal("%s: couldn't put hostkey %d: %s", __func__, i, ssh_err(r)); packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); nkeys++; } debug3("%s: sent %d hostkeys", __func__, nkeys); if (nkeys == 0) fatal("%s: no hostkeys", __func__); packet_send(); sshbuf_free(buf); } /* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability * of (max_startups_rate/100). the probability increases linearly until * all connections are dropped for startups > max_startups */ static int drop_connection(int startups) { int p, r; if (startups < options.max_startups_begin) return 0; if (startups >= options.max_startups) return 1; if (options.max_startups_rate == 100) return 1; p = 100 - options.max_startups_rate; p *= startups - options.max_startups_begin; p /= options.max_startups - options.max_startups_begin; p += options.max_startups_rate; r = arc4random_uniform(100); debug("drop_connection: p %d, r %d", p, r); return (r < p) ? 1 : 0; } static void usage(void) { fprintf(stderr, "%s, %s\n", SSH_RELEASE, #ifdef WITH_OPENSSL SSLeay_version(SSLEAY_VERSION) #else "without OpenSSL" #endif ); fprintf(stderr, "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" " [-E log_file] [-f config_file] [-g login_grace_time]\n" " [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n" " [-u len]\n" ); exit(1); } static void send_rexec_state(int fd, Buffer *conf) { Buffer m; debug3("%s: entering fd = %d config len %d", __func__, fd, buffer_len(conf)); /* * Protocol from reexec master to child: * string configuration * u_int ephemeral_key_follows * bignum e (only if ephemeral_key_follows == 1) * bignum n " * bignum d " * bignum iqmp " * bignum p " * bignum q " * string rngseed (only if OpenSSL is not self-seeded) */ buffer_init(&m); buffer_put_cstring(&m, buffer_ptr(conf)); #ifdef WITH_SSH1 if (sensitive_data.server_key != NULL && sensitive_data.server_key->type == KEY_RSA1) { buffer_put_int(&m, 1); buffer_put_bignum(&m, sensitive_data.server_key->rsa->e); buffer_put_bignum(&m, sensitive_data.server_key->rsa->n); buffer_put_bignum(&m, sensitive_data.server_key->rsa->d); buffer_put_bignum(&m, sensitive_data.server_key->rsa->iqmp); buffer_put_bignum(&m, sensitive_data.server_key->rsa->p); buffer_put_bignum(&m, sensitive_data.server_key->rsa->q); } else #endif buffer_put_int(&m, 0); #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_send_rng_seed(&m); #endif if (ssh_msg_send(fd, 0, &m) == -1) fatal("%s: ssh_msg_send failed", __func__); buffer_free(&m); debug3("%s: done", __func__); } static void recv_rexec_state(int fd, Buffer *conf) { Buffer m; char *cp; u_int len; debug3("%s: entering fd = %d", __func__, fd); buffer_init(&m); if (ssh_msg_recv(fd, &m) == -1) fatal("%s: ssh_msg_recv failed", __func__); if (buffer_get_char(&m) != 0) fatal("%s: rexec version mismatch", __func__); cp = buffer_get_string(&m, &len); if (conf != NULL) buffer_append(conf, cp, len + 1); free(cp); if (buffer_get_int(&m)) { #ifdef WITH_SSH1 if (sensitive_data.server_key != NULL) key_free(sensitive_data.server_key); sensitive_data.server_key = key_new_private(KEY_RSA1); buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); if (rsa_generate_additional_parameters( sensitive_data.server_key->rsa) != 0) fatal("%s: rsa_generate_additional_parameters " "error", __func__); #endif } #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_recv_rng_seed(&m); #endif buffer_free(&m); debug3("%s: done", __func__); } /* Accept a connection from inetd */ static void server_accept_inetd(int *sock_in, int *sock_out) { int fd; startup_pipe = -1; if (rexeced_flag) { close(REEXEC_CONFIG_PASS_FD); *sock_in = *sock_out = dup(STDIN_FILENO); if (!debug_flag) { startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); close(REEXEC_STARTUP_PIPE_FD); } } else { *sock_in = dup(STDIN_FILENO); *sock_out = dup(STDOUT_FILENO); } /* * We intentionally do not close the descriptors 0, 1, and 2 * as our code for setting the descriptors won't work if * ttyfd happens to be one of those. */ if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); if (!log_stderr) dup2(fd, STDERR_FILENO); if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO)) close(fd); } debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); } /* * Listen for TCP connections */ static void server_listen(void) { int ret, listen_sock, on = 1; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; if (num_listen_socks >= MAX_LISTEN_SOCKS) fatal("Too many listen sockets. " "Enlarge MAX_LISTEN_SOCKS"); if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { error("getnameinfo failed: %.100s", ssh_gai_strerror(ret)); continue; } /* Create socket for listening. */ listen_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (listen_sock < 0) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); continue; } if (set_nonblock(listen_sock) == -1) { close(listen_sock); continue; } /* * Set socket options. * Allow local port reuse in TIME_WAIT. */ if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); /* Only communicate in IPv6 over AF_INET6 sockets. */ if (ai->ai_family == AF_INET6) sock_set_v6only(listen_sock); debug("Bind to port %s on %s.", strport, ntop); /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { error("Bind to port %s on %s failed: %.200s.", strport, ntop, strerror(errno)); close(listen_sock); continue; } listen_socks[num_listen_socks] = listen_sock; num_listen_socks++; /* Start listening on the port. */ if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) fatal("listen on [%s]:%s: %.100s", ntop, strport, strerror(errno)); logit("Server listening on %s port %s.", ntop, strport); } freeaddrinfo(options.listen_addrs); if (!num_listen_socks) fatal("Cannot bind any address."); } /* * The main TCP accept loop. Note that, for the non-debug case, returns * from this function are in a forked subprocess. */ static void server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) { fd_set *fdset; int i, j, ret, maxfd; int key_used = 0, startups = 0; int startup_p[2] = { -1 , -1 }; struct sockaddr_storage from; socklen_t fromlen; pid_t pid; u_char rnd[256]; /* setup fd set for accept */ fdset = NULL; maxfd = 0; for (i = 0; i < num_listen_socks; i++) if (listen_socks[i] > maxfd) maxfd = listen_socks[i]; /* pipes connected to unauthenticated childs */ startup_pipes = xcalloc(options.max_startups, sizeof(int)); for (i = 0; i < options.max_startups; i++) startup_pipes[i] = -1; /* * Stay listening for connections until the system crashes or * the daemon is killed with a signal. */ for (;;) { if (received_sighup) sighup_restart(); free(fdset); fdset = xcalloc(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); for (i = 0; i < num_listen_socks; i++) FD_SET(listen_socks[i], fdset); for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1) FD_SET(startup_pipes[i], fdset); /* Wait in select until there is a connection. */ ret = select(maxfd+1, fdset, NULL, NULL, NULL); if (ret < 0 && errno != EINTR) error("select: %.100s", strerror(errno)); if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); exit(received_sigterm == SIGTERM ? 0 : 255); } if (key_used && key_do_regen) { generate_ephemeral_server_key(); key_used = 0; key_do_regen = 0; } if (ret < 0) continue; for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1 && FD_ISSET(startup_pipes[i], fdset)) { /* * the read end of the pipe is ready * if the child has closed the pipe * after successful authentication * or if the child has died */ close(startup_pipes[i]); startup_pipes[i] = -1; startups--; } for (i = 0; i < num_listen_socks; i++) { if (!FD_ISSET(listen_socks[i], fdset)) continue; fromlen = sizeof(from); *newsock = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen); if (*newsock < 0) { if (errno != EINTR && errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EAGAIN) error("accept: %.100s", strerror(errno)); if (errno == EMFILE || errno == ENFILE) usleep(100 * 1000); continue; } if (unset_nonblock(*newsock) == -1) { close(*newsock); continue; } if (drop_connection(startups) == 1) { debug("drop connection #%d", startups); close(*newsock); continue; } if (pipe(startup_p) == -1) { close(*newsock); continue; } if (rexec_flag && socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) { error("reexec socketpair: %s", strerror(errno)); close(*newsock); close(startup_p[0]); close(startup_p[1]); continue; } for (j = 0; j < options.max_startups; j++) if (startup_pipes[j] == -1) { startup_pipes[j] = startup_p[0]; if (maxfd < startup_p[0]) maxfd = startup_p[0]; startups++; break; } /* * Got connection. Fork a child to handle it, unless * we are in debugging mode. */ if (debug_flag) { /* * In debugging mode. Close the listening * socket, and start processing the * connection without forking. */ debug("Server will not fork when running in debugging mode."); close_listen_socks(); *sock_in = *newsock; *sock_out = *newsock; close(startup_p[0]); close(startup_p[1]); startup_pipe = -1; pid = getpid(); if (rexec_flag) { send_rexec_state(config_s[0], &cfg); close(config_s[0]); } break; } /* * Normal production daemon. Fork, and have * the child process the connection. The * parent continues listening. */ platform_pre_fork(); if ((pid = fork()) == 0) { /* * Child. Close the listening and * max_startup sockets. Start using * the accepted socket. Reinitialize * logging (since our pid has changed). * We break out of the loop to handle * the connection. */ platform_post_fork_child(); startup_pipe = startup_p[1]; close_startup_pipes(); close_listen_socks(); *sock_in = *newsock; *sock_out = *newsock; log_init(__progname, options.log_level, options.log_facility, log_stderr); if (rexec_flag) close(config_s[0]); break; } /* Parent. Stay in the loop. */ platform_post_fork_parent(pid); if (pid < 0) error("fork: %.100s", strerror(errno)); else debug("Forked child %ld.", (long)pid); close(startup_p[1]); if (rexec_flag) { send_rexec_state(config_s[0], &cfg); close(config_s[0]); close(config_s[1]); } /* * Mark that the key has been used (it * was "given" to the child). */ if ((options.protocol & SSH_PROTO_1) && key_used == 0) { /* Schedule server key regeneration alarm. */ signal(SIGALRM, key_regeneration_alarm); alarm(options.key_regeneration_time); key_used = 1; } close(*newsock); /* * Ensure that our random state differs * from that of the child */ arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); #ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); if ((RAND_bytes((u_char *)rnd, 1)) != 1) fatal("%s: RAND_bytes failed", __func__); #endif explicit_bzero(rnd, sizeof(rnd)); } /* child process check (or debug mode) */ if (num_listen_socks < 0) break; } } /* * Main program for the daemon. */ int main(int ac, char **av) { extern char *optarg; extern int optind; int r, opt, i, j, on = 1; int sock_in = -1, sock_out = -1, newsock = -1; const char *remote_ip; int remote_port; char *fp, *line, *laddr, *logfile = NULL; int config_s[2] = { -1 , -1 }; u_int n; u_int64_t ibytes, obytes; mode_t new_umask; Key *key; Key *pubkey; int keytype; Authctxt *authctxt; struct connection_info *connection_info = get_connection_info(0, 0); ssh_malloc_init(); /* must be called before any mallocs */ #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); #endif __progname = ssh_get_progname(av[0]); /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); for (i = 0; i < ac; i++) saved_argv[i] = xstrdup(av[i]); saved_argv[i] = NULL; #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ compat_init_setproctitle(ac, av); av = saved_argv; #endif if (geteuid() == 0 && setgroups(0, NULL) == -1) debug("setgroups(): %.200s", strerror(errno)); /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); /* Initialize configuration options to their default values. */ initialize_server_options(&options); /* Parse command-line arguments. */ while ((opt = getopt(ac, av, "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) { switch (opt) { case '4': options.address_family = AF_INET; break; case '6': options.address_family = AF_INET6; break; case 'f': config_file_name = optarg; break; case 'c': if (options.num_host_cert_files >= MAX_HOSTCERTS) { fprintf(stderr, "too many host certificates.\n"); exit(1); } options.host_cert_files[options.num_host_cert_files++] = derelativise_path(optarg); break; case 'd': if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) options.log_level++; break; case 'D': no_daemon_flag = 1; break; case 'E': logfile = optarg; /* FALLTHROUGH */ case 'e': log_stderr = 1; break; case 'i': inetd_flag = 1; break; case 'r': rexec_flag = 0; break; case 'R': rexeced_flag = 1; inetd_flag = 1; break; case 'Q': /* ignored */ break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; case 'b': options.server_key_bits = (int)strtonum(optarg, 256, 32768, NULL); break; case 'p': options.ports_from_cmdline = 1; if (options.num_ports >= MAX_PORTS) { fprintf(stderr, "too many ports.\n"); exit(1); } options.ports[options.num_ports++] = a2port(optarg); if (options.ports[options.num_ports-1] <= 0) { fprintf(stderr, "Bad port number.\n"); exit(1); } break; case 'g': if ((options.login_grace_time = convtime(optarg)) == -1) { fprintf(stderr, "Invalid login grace time.\n"); exit(1); } break; case 'k': if ((options.key_regeneration_time = convtime(optarg)) == -1) { fprintf(stderr, "Invalid key regeneration interval.\n"); exit(1); } break; case 'h': if (options.num_host_key_files >= MAX_HOSTKEYS) { fprintf(stderr, "too many host keys.\n"); exit(1); } options.host_key_files[options.num_host_key_files++] = derelativise_path(optarg); break; case 't': test_flag = 1; break; case 'T': test_flag = 2; break; case 'C': if (parse_server_match_testspec(connection_info, optarg) == -1) exit(1); break; case 'u': utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); if (utmp_len > HOST_NAME_MAX+1) { fprintf(stderr, "Invalid utmp length.\n"); exit(1); } break; case 'o': line = xstrdup(optarg); if (process_server_config_line(&options, line, "command-line", 0, NULL, NULL) != 0) exit(1); free(line); break; case '?': default: usage(); break; } } if (rexeced_flag || inetd_flag) rexec_flag = 0; if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/'))) fatal("sshd re-exec requires execution with an absolute path"); if (rexeced_flag) closefrom(REEXEC_MIN_FREE_FD); else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif /* If requested, redirect the logs to the specified logfile. */ if (logfile != NULL) log_redirect_stderr_to(logfile); /* * Force logging to stderr until we have loaded the private host * key (unless started from inetd) */ log_init(__progname, options.log_level == SYSLOG_LEVEL_NOT_SET ? SYSLOG_LEVEL_INFO : options.log_level, options.log_facility == SYSLOG_FACILITY_NOT_SET ? SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag); /* * Unset KRB5CCNAME, otherwise the user's session may inherit it from * root's environment */ if (getenv("KRB5CCNAME") != NULL) (void) unsetenv("KRB5CCNAME"); #ifdef _UNICOS /* Cray can define user privs drop all privs now! * Not needed on PRIV_SU systems! */ drop_cray_privs(); #endif sensitive_data.server_key = NULL; sensitive_data.ssh1_host_key = NULL; sensitive_data.have_ssh1_key = 0; sensitive_data.have_ssh2_key = 0; /* * If we're doing an extended config test, make sure we have all of * the parameters we need. If we're not doing an extended test, * do not silently ignore connection test params. */ if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) fatal("user, host and addr are all required when testing " "Match configs"); if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) fatal("Config test connection parameter (-C) provided without " "test mode (-T)"); /* Fetch our configuration */ buffer_init(&cfg); if (rexeced_flag) recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); else if (strcasecmp(config_file_name, "none") != 0) load_server_config(config_file_name, &cfg); parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, &cfg, NULL); seed_rng(); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && strcasecmp(options.authorized_keys_command, "none") != 0)) fatal("AuthorizedKeysCommand set without " "AuthorizedKeysCommandUser"); if (options.authorized_principals_command_user == NULL && (options.authorized_principals_command != NULL && strcasecmp(options.authorized_principals_command, "none") != 0)) fatal("AuthorizedPrincipalsCommand set without " "AuthorizedPrincipalsCommandUser"); /* * Check whether there is any path through configured auth methods. * Unfortunately it is not possible to verify this generally before * daemonisation in the presence of Match block, but this catches * and warns for trivial misconfigurations that could break login. */ if (options.num_auth_methods != 0) { if ((options.protocol & SSH_PROTO_1)) fatal("AuthenticationMethods is not supported with " "SSH protocol 1"); for (n = 0; n < options.num_auth_methods; n++) { if (auth2_methods_valid(options.auth_methods[n], 1) == 0) break; } if (n >= options.num_auth_methods) fatal("AuthenticationMethods cannot be satisfied by " "enabled authentication methods"); } /* set default channel AF */ channel_set_af(options.address_family); /* Check that there are no remaining arguments. */ if (optind < ac) { fprintf(stderr, "Extra argument %s.\n", av[optind]); exit(1); } debug("sshd version %s, %s", SSH_VERSION, #ifdef WITH_OPENSSL SSLeay_version(SSLEAY_VERSION) #else "without OpenSSL" #endif ); /* Store privilege separation user for later use if required. */ if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { if (use_privsep || options.kerberos_authentication) fatal("Privilege separation user %s does not exist", SSH_PRIVSEP_USER); } else { explicit_bzero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd)); privsep_pw = pwcopy(privsep_pw); free(privsep_pw->pw_passwd); privsep_pw->pw_passwd = xstrdup("*"); } endpwent(); /* load host keys */ sensitive_data.host_keys = xcalloc(options.num_host_key_files, sizeof(Key *)); sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, sizeof(Key *)); if (options.host_key_agent) { if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) setenv(SSH_AUTHSOCKET_ENV_NAME, options.host_key_agent, 1); if ((r = ssh_get_authentication_socket(NULL)) == 0) have_agent = 1; else error("Could not connect to agent \"%s\": %s", options.host_key_agent, ssh_err(r)); } for (i = 0; i < options.num_host_key_files; i++) { if (options.host_key_files[i] == NULL) continue; key = key_load_private(options.host_key_files[i], "", NULL); pubkey = key_load_public(options.host_key_files[i], NULL); if (pubkey == NULL && key != NULL) pubkey = key_demote(key); sensitive_data.host_keys[i] = key; sensitive_data.host_pubkeys[i] = pubkey; if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && have_agent) { debug("will rely on agent for hostkey %s", options.host_key_files[i]); keytype = pubkey->type; } else if (key != NULL) { keytype = key->type; } else { error("Could not load host key: %s", options.host_key_files[i]); sensitive_data.host_keys[i] = NULL; sensitive_data.host_pubkeys[i] = NULL; continue; } switch (keytype) { case KEY_RSA1: sensitive_data.ssh1_host_key = key; sensitive_data.have_ssh1_key = 1; break; case KEY_RSA: case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: if (have_agent || key != NULL) sensitive_data.have_ssh2_key = 1; break; } if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal("sshkey_fingerprint failed"); debug("%s host key #%d: %s %s", key ? "private" : "agent", i, keytype == KEY_RSA1 ? sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); free(fp); } if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { logit("Disabling protocol version 2. Could not load host key"); options.protocol &= ~SSH_PROTO_2; } if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); } /* * Load certificates. They are stored in an array at identical * indices to the public keys that they relate to. */ sensitive_data.host_certificates = xcalloc(options.num_host_key_files, sizeof(Key *)); for (i = 0; i < options.num_host_key_files; i++) sensitive_data.host_certificates[i] = NULL; for (i = 0; i < options.num_host_cert_files; i++) { if (options.host_cert_files[i] == NULL) continue; key = key_load_public(options.host_cert_files[i], NULL); if (key == NULL) { error("Could not load host certificate: %s", options.host_cert_files[i]); continue; } if (!key_is_cert(key)) { error("Certificate file is not a certificate: %s", options.host_cert_files[i]); key_free(key); continue; } /* Find matching private key */ for (j = 0; j < options.num_host_key_files; j++) { if (key_equal_public(key, sensitive_data.host_keys[j])) { sensitive_data.host_certificates[j] = key; break; } } if (j >= options.num_host_key_files) { error("No matching private key for certificate: %s", options.host_cert_files[i]); key_free(key); continue; } sensitive_data.host_certificates[j] = key; debug("host certificate: #%d type %d %s", j, key->type, key_type(key)); } #ifdef WITH_SSH1 /* Check certain values for sanity. */ if (options.protocol & SSH_PROTO_1) { if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { fprintf(stderr, "Bad server key size.\n"); exit(1); } /* * Check that server and host key lengths differ sufficiently. This * is necessary to make double encryption work with rsaref. Oh, I * hate software patents. I dont know if this can go? Niels */ if (options.server_key_bits > BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED && options.server_key_bits < BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { options.server_key_bits = BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED; debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits); } } #endif if (use_privsep) { struct stat st; if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) fatal("Missing privilege separation directory: %s", _PATH_PRIVSEP_CHROOT_DIR); #ifdef HAVE_CYGWIN if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && (st.st_uid != getuid () || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) #else if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) #endif fatal("%s must be owned by root and not group or " "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); } if (test_flag > 1) { if (server_match_spec_complete(connection_info) == 1) parse_server_match_config(&options, connection_info); dump_config(&options); } /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); /* * Clear out any supplemental groups we may have inherited. This * prevents inadvertent creation of files with bad modes (in the * portable version at least, it's certainly possible for PAM * to create a file, and we can't control the code in every * module which might be used). */ if (setgroups(0, NULL) < 0) debug("setgroups() failed: %.200s", strerror(errno)); if (rexec_flag) { rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); for (i = 0; i < rexec_argc; i++) { debug("rexec_argv[%d]='%s'", i, saved_argv[i]); rexec_argv[i] = saved_argv[i]; } rexec_argv[rexec_argc] = "-R"; rexec_argv[rexec_argc + 1] = NULL; } /* Ensure that umask disallows at least group and world write */ new_umask = umask(0077) | 0022; (void) umask(new_umask); /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && (!inetd_flag || rexeced_flag)) log_stderr = 1; log_init(__progname, options.log_level, options.log_facility, log_stderr); /* * If not in debugging mode, and not started from inetd, disconnect * from the controlling terminal, and fork. The original process * exits. */ if (!(debug_flag || inetd_flag || no_daemon_flag)) { #ifdef TIOCNOTTY int fd; #endif /* TIOCNOTTY */ if (daemon(0, 0) < 0) fatal("daemon() failed: %.200s", strerror(errno)); /* Disconnect from the controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ } /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Chdir to the root directory so that the current disk can be unmounted if desired. */ if (chdir("/") == -1) error("chdir(\"/\"): %s", strerror(errno)); /* ignore SIGPIPE */ signal(SIGPIPE, SIG_IGN); /* Get a connection, either from inetd or a listening TCP socket */ if (inetd_flag) { server_accept_inetd(&sock_in, &sock_out); } else { platform_pre_listen(); server_listen(); if (options.protocol & SSH_PROTO_1) generate_ephemeral_server_key(); signal(SIGHUP, sighup_handler); signal(SIGCHLD, main_sigchld_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); /* * Write out the pid file after the sigterm handler * is setup and the listen sockets are bound */ if (options.pid_file != NULL && !debug_flag) { FILE *f = fopen(options.pid_file, "w"); if (f == NULL) { error("Couldn't create pid file \"%s\": %s", options.pid_file, strerror(errno)); } else { fprintf(f, "%ld\n", (long) getpid()); fclose(f); } } /* Accept a connection and return in a forked child */ server_accept_loop(&sock_in, &sock_out, &newsock, config_s); } /* This is the child processing a new connection. */ setproctitle("%s", "[accepted]"); /* * Create a new session and process group since the 4.4BSD * setlogin() affects the entire process group. We don't * want the child to be able to affect the parent. */ #if !defined(SSHD_ACQUIRES_CTTY) /* * If setsid is called, on some platforms sshd will later acquire a * controlling terminal which will result in "could not set * controlling tty" errors. */ if (!debug_flag && !inetd_flag && setsid() < 0) error("setsid: %.100s", strerror(errno)); #endif if (rexec_flag) { int fd; debug("rexec start in %d out %d newsock %d pipe %d sock %d", sock_in, sock_out, newsock, startup_pipe, config_s[0]); dup2(newsock, STDIN_FILENO); dup2(STDIN_FILENO, STDOUT_FILENO); if (startup_pipe == -1) close(REEXEC_STARTUP_PIPE_FD); else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); close(startup_pipe); startup_pipe = REEXEC_STARTUP_PIPE_FD; } dup2(config_s[1], REEXEC_CONFIG_PASS_FD); close(config_s[1]); execv(rexec_argv[0], rexec_argv); /* Reexec has failed, fall back and continue */ error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Clean up fds */ close(REEXEC_CONFIG_PASS_FD); newsock = sock_out = sock_in = dup(STDIN_FILENO); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); if (fd > STDERR_FILENO) close(fd); } debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", sock_in, sock_out, newsock, startup_pipe, config_s[0]); } /* Executed child processes don't need these. */ fcntl(sock_out, F_SETFD, FD_CLOEXEC); fcntl(sock_in, F_SETFD, FD_CLOEXEC); /* * Disable the key regeneration alarm. We will not regenerate the * key since we are no longer in a position to give it to anyone. We * will not restart on SIGHUP since it no longer makes sense. */ alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); signal(SIGINT, SIG_DFL); /* * Register our connection. This turns encryption off because we do * not have a key. */ packet_set_connection(sock_in, sock_out); packet_set_server(); /* Set SO_KEEPALIVE if requested. */ if (options.tcp_keep_alive && packet_connection_is_on_socket() && setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); if ((remote_port = get_remote_port()) < 0) { debug("get_remote_port failed"); cleanup_exit(255); } /* * We use get_canonical_hostname with usedns = 0 instead of * get_remote_ipaddr here so IP options will be checked. */ (void) get_canonical_hostname(0); /* * The rest of the code depends on the fact that * get_remote_ipaddr() caches the remote ip, even if * the socket goes away. */ remote_ip = get_remote_ipaddr(); #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif /* Log the connection. */ laddr = get_local_ipaddr(sock_in); verbose("Connection from %s port %d on %s port %d", remote_ip, remote_port, laddr, get_local_port()); free(laddr); /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is * cleared after successful authentication. A limit of zero * indicates no limit. Note that we don't set the alarm in debugging * mode; it is just annoying to have the server exit just when you * are about to discover the bug. */ signal(SIGALRM, grace_alarm_handler); if (!debug_flag) alarm(options.login_grace_time); sshd_exchange_identification(sock_in, sock_out); /* In inetd mode, generate ephemeral key only for proto 1 connections */ if (!compat20 && inetd_flag && sensitive_data.server_key == NULL) generate_ephemeral_server_key(); packet_set_nonblocking(); /* allocate authentication context */ authctxt = xcalloc(1, sizeof(*authctxt)); authctxt->loginmsg = &loginmsg; /* XXX global for cleanup, access from other modules */ the_authctxt = authctxt; /* prepare buffer to collect messages to display to user after login */ buffer_init(&loginmsg); auth_debug_reset(); if (use_privsep) { if (privsep_preauth(authctxt) == 1) goto authenticated; } else if (compat20 && have_agent) { if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { error("Unable to get agent socket: %s", ssh_err(r)); have_agent = 0; } } /* perform the key exchange */ /* authenticate user and start session */ if (compat20) { do_ssh2_kex(); do_authentication2(authctxt); } else { #ifdef WITH_SSH1 do_ssh1_kex(); do_authentication(authctxt); #else fatal("ssh1 not supported"); #endif } /* * If we use privilege separation, the unprivileged child transfers * the current keystate and exits */ if (use_privsep) { mm_send_keystate(pmonitor); exit(0); } authenticated: /* * Cancel the alarm we set to limit the time taken for * authentication. */ alarm(0); signal(SIGALRM, SIG_DFL); authctxt->authenticated = 1; if (startup_pipe != -1) { close(startup_pipe); startup_pipe = -1; } #ifdef SSH_AUDIT_EVENTS audit_event(SSH_AUTH_SUCCESS); #endif #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); ssh_gssapi_storecreds(); restore_uid(); } #endif #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(1); do_pam_session(); } #endif /* * In privilege separation, we fork another child and prepare * file descriptor passing. */ if (use_privsep) { privsep_postauth(authctxt); /* the monitor process [priv] will not return */ if (!compat20) destroy_sensitive_data(); } packet_set_timeout(options.client_alive_interval, options.client_alive_count_max); /* Try to send all our hostkeys to the client */ if (compat20) notify_hostkeys(active_state); /* Start session. */ do_authenticated(authctxt); /* The connection has been terminated. */ packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); verbose("Closing connection to %.500s port %d", remote_ip, remote_port); #ifdef USE_PAM if (options.use_pam) finish_pam(); #endif /* USE_PAM */ #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); #endif packet_close(); if (use_privsep) mm_terminate(); exit(0); } #ifdef WITH_SSH1 /* * Decrypt session_key_int using our private server key and private host key * (key with larger modulus first). */ int ssh1_session_key(BIGNUM *session_key_int) { int rsafail = 0; if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { /* Server key has bigger modulus. */ if (BN_num_bits(sensitive_data.server_key->rsa->n) < BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { fatal("do_connection: %s: " "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", get_remote_ipaddr(), BN_num_bits(sensitive_data.server_key->rsa->n), BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), SSH_KEY_BITS_RESERVED); } if (rsa_private_decrypt(session_key_int, session_key_int, sensitive_data.server_key->rsa) != 0) rsafail++; if (rsa_private_decrypt(session_key_int, session_key_int, sensitive_data.ssh1_host_key->rsa) != 0) rsafail++; } else { /* Host key has bigger modulus (or they are equal). */ if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { fatal("do_connection: %s: " "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", get_remote_ipaddr(), BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), BN_num_bits(sensitive_data.server_key->rsa->n), SSH_KEY_BITS_RESERVED); } if (rsa_private_decrypt(session_key_int, session_key_int, sensitive_data.ssh1_host_key->rsa) != 0) rsafail++; if (rsa_private_decrypt(session_key_int, session_key_int, sensitive_data.server_key->rsa) != 0) rsafail++; } return (rsafail); } /* * SSH1 key exchange */ static void do_ssh1_kex(void) { int i, len; int rsafail = 0; BIGNUM *session_key_int, *fake_key_int, *real_key_int; u_char session_key[SSH_SESSION_KEY_LENGTH]; u_char fake_key_bytes[4096 / 8]; size_t fake_key_len; u_char cookie[8]; u_int cipher_type, auth_mask, protocol_flags; /* * Generate check bytes that the client must send back in the user * packet in order for it to be accepted; this is used to defy ip * spoofing attacks. Note that this only works against somebody * doing IP spoofing from a remote machine; any machine on the local * network can still see outgoing packets and catch the random * cookie. This only affects rhosts authentication, and this is one * of the reasons why it is inherently insecure. */ arc4random_buf(cookie, sizeof(cookie)); /* * Send our public key. We include in the packet 64 bits of random * data that must be matched in the reply in order to prevent IP * spoofing. */ packet_start(SSH_SMSG_PUBLIC_KEY); for (i = 0; i < 8; i++) packet_put_char(cookie[i]); /* Store our public server RSA key. */ packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); packet_put_bignum(sensitive_data.server_key->rsa->e); packet_put_bignum(sensitive_data.server_key->rsa->n); /* Store our public host RSA key. */ packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); /* Put protocol flags. */ packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); /* Declare which ciphers we support. */ packet_put_int(cipher_mask_ssh1(0)); /* Declare supported authentication types. */ auth_mask = 0; if (options.rhosts_rsa_authentication) auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; if (options.rsa_authentication) auth_mask |= 1 << SSH_AUTH_RSA; if (options.challenge_response_authentication == 1) auth_mask |= 1 << SSH_AUTH_TIS; if (options.password_authentication) auth_mask |= 1 << SSH_AUTH_PASSWORD; packet_put_int(auth_mask); /* Send the packet and wait for it to be sent. */ packet_send(); packet_write_wait(); debug("Sent %d bit server key and %d bit host key.", BN_num_bits(sensitive_data.server_key->rsa->n), BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); /* Read clients reply (cipher type and session key). */ packet_read_expect(SSH_CMSG_SESSION_KEY); /* Get cipher type and check whether we accept this. */ cipher_type = packet_get_char(); if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) packet_disconnect("Warning: client selects unsupported cipher."); /* Get check bytes from the packet. These must match those we sent earlier with the public key packet. */ for (i = 0; i < 8; i++) if (cookie[i] != packet_get_char()) packet_disconnect("IP Spoofing check bytes do not match."); debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ if ((real_key_int = BN_new()) == NULL) fatal("do_ssh1_kex: BN_new failed"); packet_get_bignum(real_key_int); protocol_flags = packet_get_int(); packet_set_protocol_flags(protocol_flags); packet_check_eom(); /* Setup a fake key in case RSA decryption fails */ if ((fake_key_int = BN_new()) == NULL) fatal("do_ssh1_kex: BN_new failed"); fake_key_len = BN_num_bytes(real_key_int); if (fake_key_len > sizeof(fake_key_bytes)) fake_key_len = sizeof(fake_key_bytes); arc4random_buf(fake_key_bytes, fake_key_len); if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL) fatal("do_ssh1_kex: BN_bin2bn failed"); /* Decrypt real_key_int using host/server keys */ rsafail = PRIVSEP(ssh1_session_key(real_key_int)); /* If decryption failed, use the fake key. Else, the real key. */ if (rsafail) session_key_int = fake_key_int; else session_key_int = real_key_int; /* * Extract session key from the decrypted integer. The key is in the * least significant 256 bits of the integer; the first byte of the * key is in the highest bits. */ (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); len = BN_num_bytes(session_key_int); if (len < 0 || (u_int)len > sizeof(session_key)) { error("do_ssh1_kex: bad session key len from %s: " "session_key_int %d > sizeof(session_key) %lu", get_remote_ipaddr(), len, (u_long)sizeof(session_key)); rsafail++; } else { explicit_bzero(session_key, sizeof(session_key)); BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); derive_ssh1_session_id( sensitive_data.ssh1_host_key->rsa->n, sensitive_data.server_key->rsa->n, cookie, session_id); /* * Xor the first 16 bytes of the session key with the * session id. */ for (i = 0; i < 16; i++) session_key[i] ^= session_id[i]; } /* Destroy the private and public keys. No longer. */ destroy_sensitive_data(); if (use_privsep) mm_ssh1_session_id(session_id); /* Destroy the decrypted integer. It is no longer needed. */ BN_clear_free(real_key_int); BN_clear_free(fake_key_int); /* Set the session key. From this on all communications will be encrypted. */ packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); /* Destroy our copy of the session key. It is no longer needed. */ explicit_bzero(session_key, sizeof(session_key)); debug("Received session key; encryption turned on."); /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); } #endif int sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, const u_char *data, size_t dlen, const char *alg, u_int flag) { int r; u_int xxx_slen, xxx_dlen = dlen; if (privkey) { if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen, alg) < 0)) fatal("%s: key_sign failed", __func__); if (slen) *slen = xxx_slen; } else if (use_privsep) { if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen, alg) < 0) fatal("%s: pubkey_sign failed", __func__); if (slen) *slen = xxx_slen; } else { if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, data, dlen, alg, datafellows)) != 0) fatal("%s: ssh_agent_sign failed: %s", __func__, ssh_err(r)); } return 0; } /* SSH2 key exchange */ static void do_ssh2_kex(void) { char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; struct kex *kex; int r; myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( options.ciphers); myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal( options.ciphers); myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; if (options.compression == COMP_NONE) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; } else if (options.compression == COMP_DELAYED) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com"; } if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, (time_t)options.rekey_interval); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); kex = active_state->kex; #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kexecdh_server; # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; kex->sign = sshd_hostkey_sign; dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); session_id2 = kex->session_id; session_id2_len = kex->session_id_len; #ifdef DEBUG_KEXDH /* send 1st encrypted/maced/compressed message */ packet_start(SSH2_MSG_IGNORE); packet_put_cstring("markus"); packet_send(); packet_write_wait(); #endif debug("KEX done"); } /* server specific fatal cleanup */ void cleanup_exit(int i) { if (the_authctxt) { do_cleanup(the_authctxt); if (use_privsep && privsep_is_preauth && pmonitor != NULL && pmonitor->m_pid > 1) { debug("Killing privsep child %d", pmonitor->m_pid); if (kill(pmonitor->m_pid, SIGKILL) != 0 && errno != ESRCH) error("%s: kill(%d): %s", __func__, pmonitor->m_pid, strerror(errno)); } } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ if (!use_privsep || mm_is_monitor()) audit_event(SSH_CONNECTION_ABANDON); #endif _exit(i); } openssh-7.2p2/sshd_config010064400017500001750000000070521267006270000136670ustar00djmdjm# $OpenBSD: sshd_config,v 1.98 2016/02/17 05:29:04 djm Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. # This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin # The strategy used for options in the default sshd_config shipped with # OpenSSH is to specify options with their default value where # possible, but leave them commented. Uncommented options override the # default value. #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: # The default requires explicit activation of protocol 1 #Protocol 2 # HostKey for protocol version 1 #HostKey /etc/ssh/ssh_host_key # HostKeys for protocol version 2 #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key #HostKey /etc/ssh/ssh_host_ecdsa_key #HostKey /etc/ssh/ssh_host_ed25519_key # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h #ServerKeyBits 1024 # Ciphers and keying #RekeyLimit default none # Logging # obsoletes QuietMode and FascistLogging #SyslogFacility AUTH #LogLevel INFO # Authentication: #LoginGraceTime 2m #PermitRootLogin prohibit-password #StrictModes yes #MaxAuthTries 6 #MaxSessions 10 #RSAAuthentication yes #PubkeyAuthentication yes # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 # but this is overridden so installations will only check .ssh/authorized_keys AuthorizedKeysFile .ssh/authorized_keys #AuthorizedPrincipalsFile none #AuthorizedKeysCommand none #AuthorizedKeysCommandUser nobody # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts #RhostsRSAAuthentication no # similar for protocol version 2 #HostbasedAuthentication no # Change to yes if you don't trust ~/.ssh/known_hosts for # RhostsRSAAuthentication and HostbasedAuthentication #IgnoreUserKnownHosts no # Don't read the user's ~/.rhosts and ~/.shosts files #IgnoreRhosts yes # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no # Change to no to disable s/key passwords #ChallengeResponseAuthentication yes # Kerberos options #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosGetAFSToken no # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass # the setting of "PermitRootLogin without-password". # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and ChallengeResponseAuthentication to 'no'. #UsePAM no #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no #X11Forwarding no #X11DisplayOffset 10 #X11UseLocalhost yes #PermitTTY yes #PrintMotd yes #PrintLastLog yes #TCPKeepAlive yes #UseLogin no #UsePrivilegeSeparation sandbox #PermitUserEnvironment no #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 #UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 #PermitTunnel no #ChrootDirectory none #VersionAddendum none # no default banner path #Banner none # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server openssh-7.2p2/sshd_config.5010064400017500001750000001376411267006270000140420ustar00djmdjm.\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $OpenBSD: sshd_config.5,v 1.220 2016/02/17 08:57:34 djm Exp $ .Dd $Mdocdate: February 17 2016 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME .Nm sshd_config .Nd OpenSSH SSH daemon configuration file .Sh SYNOPSIS .Nm /etc/ssh/sshd_config .Sh DESCRIPTION .Xr sshd 8 reads configuration data from .Pa /etc/ssh/sshd_config (or the file specified with .Fl f on the command line). The file contains keyword-argument pairs, one per line. Lines starting with .Ql # and empty lines are interpreted as comments. Arguments may optionally be enclosed in double quotes .Pq \&" in order to represent arguments containing spaces. .Pp The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): .Bl -tag -width Ds .It Cm AcceptEnv Specifies what environment variables sent by the client will be copied into the session's .Xr environ 7 . See .Cm SendEnv in .Xr ssh_config 5 for how to configure the client. The .Ev TERM environment variable is always sent whenever the client requests a pseudo-terminal as it is required by the protocol. Variables are specified by name, which may contain the wildcard characters .Ql * and .Ql \&? . Multiple environment variables may be separated by whitespace or spread across multiple .Cm AcceptEnv directives. Be warned that some environment variables could be used to bypass restricted user environments. For this reason, care should be taken in the use of this directive. The default is not to accept any environment variables. .It Cm AddressFamily Specifies which address family should be used by .Xr sshd 8 . Valid arguments are .Dq any , .Dq inet (use IPv4 only), or .Dq inet6 (use IPv6 only). The default is .Dq any . .It Cm AllowAgentForwarding Specifies whether .Xr ssh-agent 1 forwarding is permitted. The default is .Dq yes . Note that disabling agent forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny directives are processed in the following order: .Cm DenyUsers , .Cm AllowUsers , .Cm DenyGroups , and finally .Cm AllowGroups . .Pp See PATTERNS in .Xr ssh_config 5 for more information on patterns. .It Cm AllowTcpForwarding Specifies whether TCP forwarding is permitted. The available options are .Dq yes or .Dq all to allow TCP forwarding, .Dq no to prevent all TCP forwarding, .Dq local to allow local (from the perspective of .Xr ssh 1 ) forwarding only or .Dq remote to allow remote forwarding only. The default is .Dq yes . Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. .It Cm AllowStreamLocalForwarding Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. The available options are .Dq yes or .Dq all to allow StreamLocal forwarding, .Dq no to prevent all StreamLocal forwarding, .Dq local to allow local (from the perspective of .Xr ssh 1 ) forwarding only or .Dq remote to allow remote forwarding only. The default is .Dq yes . Note that disabling StreamLocal forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. .It Cm AllowUsers This keyword can be followed by a list of user name patterns, separated by spaces. If specified, login is allowed only for user names that match one of the patterns. Only user names are valid; a numerical user ID is not recognized. By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. The allow/deny directives are processed in the following order: .Cm DenyUsers , .Cm AllowUsers , .Cm DenyGroups , and finally .Cm AllowGroups . .Pp See PATTERNS in .Xr ssh_config 5 for more information on patterns. .It Cm AuthenticationMethods Specifies the authentication methods that must be successfully completed for a user to be granted access. This option must be followed by one or more comma-separated lists of authentication method names. Successful authentication requires completion of every method in at least one of these lists. .Pp For example, an argument of .Dq publickey,password publickey,keyboard-interactive would require the user to complete public key authentication, followed by either password or keyboard interactive authentication. Only methods that are next in one or more lists are offered at each stage, so for this example, it would not be possible to attempt password or keyboard-interactive authentication before public key. .Pp For keyboard interactive authentication it is also possible to restrict authentication to a specific device by appending a colon followed by the device identifier .Dq bsdauth , .Dq pam , or .Dq skey , depending on the server configuration. For example, .Dq keyboard-interactive:bsdauth would restrict keyboard interactive authentication to the .Dq bsdauth device. .Pp If the .Dq publickey method is listed more than once, .Xr sshd 8 verifies that keys that have been used successfully are not reused for subsequent authentications. For example, an .Cm AuthenticationMethods of .Dq publickey,publickey will require successful authentication using two different public keys. .Pp This option will yield a fatal error if enabled if protocol 1 is also enabled. Note that each authentication method listed should also be explicitly enabled in the configuration. The default is not to require multiple authentication; successful completion of a single authentication method is sufficient. .It Cm AuthorizedKeysCommand Specifies a program to be used to look up the user's public keys. The program must be owned by root, not writable by group or others and specified by an absolute path. .Pp Arguments to .Cm AuthorizedKeysCommand may be provided using the following tokens, which will be expanded at runtime: %% is replaced by a literal '%', %u is replaced by the username being authenticated, %h is replaced by the home directory of the user being authenticated, %t is replaced with the key type offered for authentication, %f is replaced with the fingerprint of the key, and %k is replaced with the key being offered for authentication. If no arguments are specified then the username of the target user will be supplied. .Pp The program should produce on standard output zero or more lines of authorized_keys output (see AUTHORIZED_KEYS in .Xr sshd 8 ) . If a key supplied by AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual .Cm AuthorizedKeysFile files. By default, no AuthorizedKeysCommand is run. .It Cm AuthorizedKeysCommandUser Specifies the user under whose account the AuthorizedKeysCommand is run. It is recommended to use a dedicated user that has no other role on the host than running authorized keys commands. If .Cm AuthorizedKeysCommand is specified but .Cm AuthorizedKeysCommandUser is not, then .Xr sshd 8 will refuse to start. .It Cm AuthorizedKeysFile Specifies the file that contains the public keys that can be used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of .Xr sshd 8 . .Cm AuthorizedKeysFile may contain tokens of the form %T which are substituted during connection setup. The following tokens are defined: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. After expansion, .Cm AuthorizedKeysFile is taken to be an absolute path or one relative to the user's home directory. Multiple files may be listed, separated by whitespace. Alternately this option may be set to .Dq none to skip checking for user keys in files. The default is .Dq .ssh/authorized_keys .ssh/authorized_keys2 . .It Cm AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed certificate principals as per .Cm AuthorizedPrincipalsFile . The program must be owned by root, not writable by group or others and specified by an absolute path. .Pp Arguments to .Cm AuthorizedPrincipalsCommand may be provided using the following tokens, which will be expanded at runtime: %% is replaced by a literal '%', %u is replaced by the username being authenticated and %h is replaced by the home directory of the user being authenticated. .Pp The program should produce on standard output zero or more lines of .Cm AuthorizedPrincipalsFile output. If either .Cm AuthorizedPrincipalsCommand or .Cm AuthorizedPrincipalsFile is specified, then certificates offered by the client for authentication must contain a principal that is listed. By default, no AuthorizedPrincipalsCommand is run. .It Cm AuthorizedPrincipalsCommandUser Specifies the user under whose account the AuthorizedPrincipalsCommand is run. It is recommended to use a dedicated user that has no other role on the host than running authorized principals commands. If .Cm AuthorizedPrincipalsCommand is specified but .Cm AuthorizedPrincipalsCommandUser is not, then .Xr sshd 8 will refuse to start. .It Cm AuthorizedPrincipalsFile Specifies a file that lists principal names that are accepted for certificate authentication. When using certificates signed by a key listed in .Cm TrustedUserCAKeys , this file lists names, one of which must appear in the certificate for it to be accepted for authentication. Names are listed one per line preceded by key options (as described in AUTHORIZED_KEYS FILE FORMAT in .Xr sshd 8 ) . Empty lines and comments starting with .Ql # are ignored. .Pp .Cm AuthorizedPrincipalsFile may contain tokens of the form %T which are substituted during connection setup. The following tokens are defined: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. After expansion, .Cm AuthorizedPrincipalsFile is taken to be an absolute path or one relative to the user's home directory. .Pp The default is .Dq none , i.e. not to use a principals file \(en in this case, the username of the user must appear in a certificate's principals list for it to be accepted. Note that .Cm AuthorizedPrincipalsFile is only used when authentication proceeds using a CA listed in .Cm TrustedUserCAKeys and is not consulted for certification authorities trusted via .Pa ~/.ssh/authorized_keys , though the .Cm principals= key option offers a similar facility (see .Xr sshd 8 for details). .It Cm Banner The contents of the specified file are sent to the remote user before authentication is allowed. If the argument is .Dq none then no banner is displayed. By default, no banner is displayed. .It Cm ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed (e.g. via PAM or through authentication styles supported in .Xr login.conf 5 ) The default is .Dq yes . .It Cm ChrootDirectory Specifies the pathname of a directory to .Xr chroot 2 to after authentication. At session startup .Xr sshd 8 checks that all components of the pathname are root-owned directories which are not writable by any other user or group. After the chroot, .Xr sshd 8 changes the working directory to the user's home directory. .Pp The pathname may contain the following tokens that are expanded at runtime once the connecting user has been authenticated: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. .Pp The .Cm ChrootDirectory must contain the necessary files and directories to support the user's session. For an interactive session this requires at least a shell, typically .Xr sh 1 , and basic .Pa /dev nodes such as .Xr null 4 , .Xr zero 4 , .Xr stdin 4 , .Xr stdout 4 , .Xr stderr 4 , and .Xr tty 4 devices. For file transfer sessions using .Dq sftp , no additional configuration of the environment is necessary if the in-process sftp server is used, though sessions which use logging may require .Pa /dev/log inside the chroot directory on some operating systems (see .Xr sftp-server 8 for details). .Pp For safety, it is very important that the directory hierarchy be prevented from modification by other processes on the system (especially those outside the jail). Misconfiguration can lead to unsafe environments which .Xr sshd 8 cannot detect. .Pp The default is .Dq none , indicating not to .Xr chroot 2 . .It Cm Ciphers Specifies the ciphers allowed. Multiple ciphers must be comma-separated. If the specified value begins with a .Sq + character, then the specified ciphers will be appended to the default set instead of replacing them. .Pp The supported ciphers are: .Pp .Bl -item -compact -offset indent .It 3des-cbc .It aes128-cbc .It aes192-cbc .It aes256-cbc .It aes128-ctr .It aes192-ctr .It aes256-ctr .It aes128-gcm@openssh.com .It aes256-gcm@openssh.com .It arcfour .It arcfour128 .It arcfour256 .It blowfish-cbc .It cast128-cbc .It chacha20-poly1305@openssh.com .El .Pp The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com .Ed .Pp The list of available ciphers may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq cipher . .It Cm ClientAliveCountMax Sets the number of client alive messages (see below) which may be sent without .Xr sshd 8 receiving any messages back from the client. If this threshold is reached while client alive messages are being sent, sshd will disconnect the client, terminating the session. It is important to note that the use of client alive messages is very different from .Cm TCPKeepAlive (below). The client alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by .Cm TCPKeepAlive is spoofable. The client alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive. .Pp The default value is 3. If .Cm ClientAliveInterval (see below) is set to 15, and .Cm ClientAliveCountMax is left at the default, unresponsive SSH clients will be disconnected after approximately 45 seconds. .It Cm ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, .Xr sshd 8 will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. .It Cm Compression Specifies whether compression is allowed, or delayed until the user has authenticated successfully. The argument must be .Dq yes , .Dq delayed , or .Dq no . The default is .Dq delayed . .It Cm DenyGroups This keyword can be followed by a list of group name patterns, separated by spaces. Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny directives are processed in the following order: .Cm DenyUsers , .Cm AllowUsers , .Cm DenyGroups , and finally .Cm AllowGroups . .Pp See PATTERNS in .Xr ssh_config 5 for more information on patterns. .It Cm DenyUsers This keyword can be followed by a list of user name patterns, separated by spaces. Login is disallowed for user names that match one of the patterns. Only user names are valid; a numerical user ID is not recognized. By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. The allow/deny directives are processed in the following order: .Cm DenyUsers , .Cm AllowUsers , .Cm DenyGroups , and finally .Cm AllowGroups . .Pp See PATTERNS in .Xr ssh_config 5 for more information on patterns. .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: .Dq md5 and .Dq sha256 . The default is .Dq sha256 . .It Cm ForceCommand Forces the execution of the command specified by .Cm ForceCommand , ignoring any command supplied by the client and .Pa ~/.ssh/rc if present. The command is invoked by using the user's login shell with the -c option. This applies to shell, command, or subsystem execution. It is most useful inside a .Cm Match block. The command originally supplied by the client is available in the .Ev SSH_ORIGINAL_COMMAND environment variable. Specifying a command of .Dq internal-sftp will force the use of an in-process sftp server that requires no support files when used with .Cm ChrootDirectory . The default is .Dq none . .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. By default, .Xr sshd 8 binds remote port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. .Cm GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to connect. The argument may be .Dq no to force remote port forwardings to be available to the local host only, .Dq yes to force remote port forwardings to bind to the wildcard address, or .Dq clientspecified to allow the client to select the address to which the forwarding is bound. The default is .Dq no . .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Dq yes . .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If set to .Dq yes then the client must authenticate against the .Pa host service on the current hostname. If set to .Dq no then the client may authenticate against any service key stored in the machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Dq yes . .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. Alternately if the specified value begins with a .Sq + character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp The .Fl Q option of .Xr ssh 1 may be used to list supported key types. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed (host-based authentication). The default is .Dq no . .It Cm HostbasedUsesNameFromPacketOnly Specifies whether or not the server will attempt to perform a reverse name lookup when matching the name in the .Pa ~/.shosts , .Pa ~/.rhosts , and .Pa /etc/hosts.equiv files during .Cm HostbasedAuthentication . A setting of .Dq yes means that .Xr sshd 8 uses the name supplied by the client rather than attempting to resolve the name from the TCP connection itself. The default is .Dq no . .It Cm HostCertificate Specifies a file containing a public host certificate. The certificate's public key must match a private host key already specified by .Cm HostKey . The default behaviour of .Xr sshd 8 is not to load any certificates. .It Cm HostKey Specifies a file containing a private host key used by SSH. The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and .Pa /etc/ssh/ssh_host_dsa_key , .Pa /etc/ssh/ssh_host_ecdsa_key , .Pa /etc/ssh/ssh_host_ed25519_key and .Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. .Pp Note that .Xr sshd 8 will refuse to use a file if it is group/world-accessible and that the .Cm HostKeyAlgorithms option restricts which of the keys are actually used by .Xr sshd 8 . .Pp It is possible to have multiple host key files. .Dq rsa1 keys are used for version 1 and .Dq dsa , .Dq ecdsa , .Dq ed25519 or .Dq rsa are used for version 2 of the SSH protocol. It is also possible to specify public host key files instead. In this case operations on the private key will be delegated to an .Xr ssh-agent 1 . .It Cm HostKeyAgent Identifies the UNIX-domain socket used to communicate with an agent that has access to the private host keys. If .Dq SSH_AUTH_SOCK is specified, the location of the socket will be read from the .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms Specifies the host key algorithms that the server offers. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp The list of available key types may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq key . .It Cm IgnoreRhosts Specifies that .Pa .rhosts and .Pa .shosts files will not be used in .Cm RhostsRSAAuthentication or .Cm HostbasedAuthentication . .Pp .Pa /etc/hosts.equiv and .Pa /etc/shosts.equiv are still used. The default is .Dq yes . .It Cm IgnoreUserKnownHosts Specifies whether .Xr sshd 8 should ignore the user's .Pa ~/.ssh/known_hosts during .Cm RhostsRSAAuthentication or .Cm HostbasedAuthentication . The default is .Dq no . .It Cm IPQoS Specifies the IPv4 type-of-service or DSCP class for the connection. Accepted values are .Dq af11 , .Dq af12 , .Dq af13 , .Dq af21 , .Dq af22 , .Dq af23 , .Dq af31 , .Dq af32 , .Dq af33 , .Dq af41 , .Dq af42 , .Dq af43 , .Dq cs0 , .Dq cs1 , .Dq cs2 , .Dq cs3 , .Dq cs4 , .Dq cs5 , .Dq cs6 , .Dq cs7 , .Dq ef , .Dq lowdelay , .Dq throughput , .Dq reliability , or a numeric value. This option may take one or two arguments, separated by whitespace. If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is .Dq lowdelay for interactive sessions and .Dq throughput for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. The argument to this keyword must be .Dq yes or .Dq no . The default is to use whatever value .Cm ChallengeResponseAuthentication is set to (by default .Dq yes ) . .It Cm KerberosAuthentication Specifies whether the password provided by the user for .Cm PasswordAuthentication will be validated through the Kerberos KDC. To use this option, the server needs a Kerberos servtab which allows the verification of the KDC's identity. The default is .Dq no . .It Cm KerberosGetAFSToken If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire an AFS token before accessing the user's home directory. The default is .Dq no . .It Cm KerberosOrLocalPasswd If password authentication through Kerberos fails then the password will be validated via any additional local mechanism such as .Pa /etc/passwd . The default is .Dq yes . .It Cm KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Dq yes . .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. Alternately if the specified value begins with a .Sq + character, then the specified methods will be appended to the default set instead of replacing them. The supported algorithms are: .Pp .Bl -item -compact -offset indent .It curve25519-sha256@libssh.org .It diffie-hellman-group1-sha1 .It diffie-hellman-group14-sha1 .It diffie-hellman-group-exchange-sha1 .It diffie-hellman-group-exchange-sha256 .It ecdh-sha2-nistp256 .It ecdh-sha2-nistp384 .It ecdh-sha2-nistp521 .El .Pp The default is: .Bd -literal -offset indent curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1 .Ed .Pp The list of available key exchange algorithms may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq kex . .It Cm KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). The purpose of regeneration is to prevent decrypting captured sessions by later breaking into the machine and stealing the keys. The key is never stored anywhere. If the value is 0, the key is never regenerated. The default is 3600 (seconds). .It Cm ListenAddress Specifies the local addresses .Xr sshd 8 should listen on. The following forms may be used: .Pp .Bl -item -offset indent -compact .It .Cm ListenAddress .Sm off .Ar host | Ar IPv4_addr | Ar IPv6_addr .Sm on .It .Cm ListenAddress .Sm off .Ar host | Ar IPv4_addr : Ar port .Sm on .It .Cm ListenAddress .Sm off .Oo .Ar host | Ar IPv6_addr Oc : Ar port .Sm on .El .Pp If .Ar port is not specified, sshd will listen on the address and all .Cm Port options specified. The default is to listen on all local addresses. Multiple .Cm ListenAddress options are permitted. .It Cm LoginGraceTime The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. The default is 120 seconds. .It Cm LogLevel Gives the verbosity level that is used when logging messages from .Xr sshd 8 . The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. Logging with a DEBUG level violates the privacy of users and is not recommended. .It Cm MACs Specifies the available MAC (message authentication code) algorithms. The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated. If the specified value begins with a .Sq + character, then the specified algorithms will be appended to the default set instead of replacing them. .Pp The algorithms that contain .Dq -etm calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. The supported MACs are: .Pp .Bl -item -compact -offset indent .It hmac-md5 .It hmac-md5-96 .It hmac-ripemd160 .It hmac-sha1 .It hmac-sha1-96 .It hmac-sha2-256 .It hmac-sha2-512 .It umac-64@openssh.com .It umac-128@openssh.com .It hmac-md5-etm@openssh.com .It hmac-md5-96-etm@openssh.com .It hmac-ripemd160-etm@openssh.com .It hmac-sha1-etm@openssh.com .It hmac-sha1-96-etm@openssh.com .It hmac-sha2-256-etm@openssh.com .It hmac-sha2-512-etm@openssh.com .It umac-64-etm@openssh.com .It umac-128-etm@openssh.com .El .Pp The default is: .Bd -literal -offset indent umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512,hmac-sha1 .Ed .Pp The list of available MAC algorithms may also be obtained using the .Fl Q option of .Xr ssh 1 with an argument of .Dq mac . .It Cm Match Introduces a conditional block. If all of the criteria on the .Cm Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another .Cm Match line or the end of the file. If a keyword appears in multiple .Cm Match blocks that are satisfied, only the first instance of the keyword is applied. .Pp The arguments to .Cm Match are one or more criteria-pattern pairs or the single token .Cm All which matches all criteria. The available criteria are .Cm User , .Cm Group , .Cm Host , .Cm LocalAddress , .Cm LocalPort , and .Cm Address . The match patterns may consist of single entries or comma-separated lists and may use the wildcard and negation operators described in the PATTERNS section of .Xr ssh_config 5 . .Pp The patterns in an .Cm Address criteria may additionally contain addresses to match in CIDR address/masklen format, e.g.\& .Dq 192.0.2.0/24 or .Dq 3ffe:ffff::/32 . Note that the mask length provided must be consistent with the address - it is an error to specify a mask length that is too long for the address or one with bits set in this host portion of the address. For example, .Dq 192.0.2.0/33 and .Dq 192.0.2.0/8 respectively. .Pp Only a subset of keywords may be used on the lines following a .Cm Match keyword. Available keywords are .Cm AcceptEnv , .Cm AllowAgentForwarding , .Cm AllowGroups , .Cm AllowStreamLocalForwarding , .Cm AllowTcpForwarding , .Cm AllowUsers , .Cm AuthenticationMethods , .Cm AuthorizedKeysCommand , .Cm AuthorizedKeysCommandUser , .Cm AuthorizedKeysFile , .Cm AuthorizedPrincipalsCommand , .Cm AuthorizedPrincipalsCommandUser , .Cm AuthorizedPrincipalsFile , .Cm Banner , .Cm ChrootDirectory , .Cm DenyGroups , .Cm DenyUsers , .Cm ForceCommand , .Cm GatewayPorts , .Cm GSSAPIAuthentication , .Cm HostbasedAcceptedKeyTypes , .Cm HostbasedAuthentication , .Cm HostbasedUsesNameFromPacketOnly , .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , .Cm PermitEmptyPasswords , .Cm PermitOpen , .Cm PermitRootLogin , .Cm PermitTTY , .Cm PermitTunnel , .Cm PermitUserRC , .Cm PubkeyAcceptedKeyTypes , .Cm PubkeyAuthentication , .Cm RekeyLimit , .Cm RevokedKeys , .Cm RhostsRSAAuthentication , .Cm RSAAuthentication , .Cm StreamLocalBindMask , .Cm StreamLocalBindUnlink , .Cm TrustedUserCAKeys , .Cm X11DisplayOffset , .Cm X11Forwarding and .Cm X11UseLocalHost . .It Cm MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. The default is 6. .It Cm MaxSessions Specifies the maximum number of open shell, login or subsystem (e.g. sftp) sessions permitted per network connection. Multiple sessions may be established by clients that support connection multiplexing. Setting .Cm MaxSessions to 1 will effectively disable session multiplexing, whereas setting it to 0 will prevent all shell, login and subsystem sessions while still permitting forwarding. The default is 10. .It Cm MaxStartups Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections will be dropped until authentication succeeds or the .Cm LoginGraceTime expires for a connection. The default is 10:30:100. .Pp Alternatively, random early drop can be enabled by specifying the three colon separated values .Dq start:rate:full (e.g. "10:30:60"). .Xr sshd 8 will refuse connection attempts with a probability of .Dq rate/100 (30%) if there are currently .Dq start (10) unauthenticated connections. The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches .Dq full (60). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is .Dq yes . .It Cm PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is .Dq no . .It Cm PermitOpen Specifies the destinations to which TCP port forwarding is permitted. The forwarding specification must be one of the following forms: .Pp .Bl -item -offset indent -compact .It .Cm PermitOpen .Sm off .Ar host : port .Sm on .It .Cm PermitOpen .Sm off .Ar IPv4_addr : port .Sm on .It .Cm PermitOpen .Sm off .Ar \&[ IPv6_addr \&] : port .Sm on .El .Pp Multiple forwards may be specified by separating them with whitespace. An argument of .Dq any can be used to remove all restrictions and permit any forwarding requests. An argument of .Dq none can be used to prohibit all forwarding requests. By default all port forwarding requests are permitted. .It Cm PermitRootLogin Specifies whether root can log in using .Xr ssh 1 . The argument must be .Dq yes , .Dq prohibit-password , .Dq without-password , .Dq forced-commands-only , or .Dq no . The default is .Dq prohibit-password . .Pp If this option is set to .Dq prohibit-password or .Dq without-password , password and keyboard-interactive authentication are disabled for root. .Pp If this option is set to .Dq forced-commands-only , root login with public key authentication will be allowed, but only if the .Ar command option has been specified (which may be useful for taking remote backups even if root login is normally not allowed). All other authentication methods are disabled for root. .Pp If this option is set to .Dq no , root is not allowed to log in. .It Cm PermitTunnel Specifies whether .Xr tun 4 device forwarding is allowed. The argument must be .Dq yes , .Dq point-to-point (layer 3), .Dq ethernet (layer 2), or .Dq no . Specifying .Dq yes permits both .Dq point-to-point and .Dq ethernet . The default is .Dq no . .Pp Independent of this setting, the permissions of the selected .Xr tun 4 device must allow access to the user. .It Cm PermitTTY Specifies whether .Xr pty 4 allocation is permitted. The default is .Dq yes . .It Cm PermitUserEnvironment Specifies whether .Pa ~/.ssh/environment and .Cm environment= options in .Pa ~/.ssh/authorized_keys are processed by .Xr sshd 8 . The default is .Dq no . Enabling environment processing may enable users to bypass access restrictions in some configurations using mechanisms such as .Ev LD_PRELOAD . .It Cm PermitUserRC Specifies whether any .Pa ~/.ssh/rc file is executed. The default is .Dq yes . .It Cm PidFile Specifies the file that contains the process ID of the SSH daemon, or .Dq none to not write one. The default is .Pa /var/run/sshd.pid . .It Cm Port Specifies the port number that .Xr sshd 8 listens on. The default is 22. Multiple options of this type are permitted. See also .Cm ListenAddress . .It Cm PrintLastLog Specifies whether .Xr sshd 8 should print the date and time of the last user login when a user logs in interactively. The default is .Dq yes . .It Cm PrintMotd Specifies whether .Xr sshd 8 should print .Pa /etc/motd when a user logs in interactively. (On some systems it is also printed by the shell, .Pa /etc/profile , or equivalent.) The default is .Dq yes . .It Cm Protocol Specifies the protocol versions .Xr sshd 8 supports. The possible values are .Sq 1 and .Sq 2 . Multiple versions must be comma-separated. The default is .Sq 2 . Protocol 1 suffers from a number of cryptographic weaknesses and should not be used. It is only offered to support legacy devices. .Pp Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. Specifying .Dq 2,1 is identical to .Dq 1,2 . .It Cm PubkeyAcceptedKeyTypes Specifies the key types that will be accepted for public key authentication as a comma-separated pattern list. Alternately if the specified value begins with a .Sq + character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: .Bd -literal -offset 3n ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa .Ed .Pp The .Fl Q option of .Xr ssh 1 may be used to list supported key types. .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is .Dq yes . .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may have a suffix of .Sq K , .Sq M , or .Sq G to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between .Sq 1G and .Sq 4G , depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the .Sx TIME FORMATS section. The default value for .Cm RekeyLimit is .Dq default none , which means that rekeying is performed after the cipher's default amount of data has been sent or received and no time based rekeying is done. .It Cm RevokedKeys Specifies revoked public keys file, or .Dq none to not use one. Keys listed in this file will be refused for public key authentication. Note that if this file is not readable, then public key authentication will be refused for all users. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by .Xr ssh-keygen 1 . For more information on KRLs, see the KEY REVOCATION LISTS section in .Xr ssh-keygen 1 . .It Cm RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The default is .Dq no . This option applies to protocol version 1 only. .It Cm RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is .Dq yes . This option applies to protocol version 1 only. .It Cm ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. The default and minimum value is 1024. .It Cm StreamLocalBindMask Sets the octal file creation mode mask .Pq umask used when creating a Unix-domain socket file for local or remote port forwarding. This option is only used for port forwarding to a Unix-domain socket file. .Pp The default value is 0177, which creates a Unix-domain socket file that is readable and writable only by the owner. Note that not all operating systems honor the file mode on Unix-domain socket files. .It Cm StreamLocalBindUnlink Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new one. If the socket file already exists and .Cm StreamLocalBindUnlink is not enabled, .Nm sshd will be unable to forward the port to the Unix-domain socket file. This option is only used for port forwarding to a Unix-domain socket file. .Pp The argument must be .Dq yes or .Dq no . The default is .Dq no . .It Cm StrictModes Specifies whether .Xr sshd 8 should check file modes and ownership of the user's files and home directory before accepting login. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is .Dq yes . Note that this does not apply to .Cm ChrootDirectory , whose permissions and ownership are checked unconditionally. .It Cm Subsystem Configures an external subsystem (e.g. file transfer daemon). Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request. .Pp The command .Xr sftp-server 8 implements the .Dq sftp file transfer subsystem. .Pp Alternately the name .Dq internal-sftp implements an in-process .Dq sftp server. This may simplify configurations using .Cm ChrootDirectory to force a different filesystem root on clients. .Pp By default no subsystems are defined. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive Specifies whether the system should send TCP keepalive messages to the other side. If they are sent, death of the connection or crash of one of the machines will be properly noticed. However, this means that connections will die if the route is down temporarily, and some people find it annoying. On the other hand, if TCP keepalives are not sent, sessions may hang indefinitely on the server, leaving .Dq ghost users and consuming server resources. .Pp The default is .Dq yes (to send TCP keepalive messages), and the server will notice if the network goes down or the client host crashes. This avoids infinitely hanging sessions. .Pp To disable TCP keepalive messages, the value should be set to .Dq no . .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or .Dq none to not use one. Keys are listed one per line; empty lines and comments starting with .Ql # are allowed. If a certificate is presented for authentication and has its signing CA key listed in this file, then it may be used for authentication for any user listed in the certificate's principals list. Note that certificates that lack a list of principals will not be permitted for authentication using .Cm TrustedUserCAKeys . For more details on certificates, see the CERTIFICATES section in .Xr ssh-keygen 1 . .It Cm UseDNS Specifies whether .Xr sshd 8 should look up the remote host name, and to check that the resolved host name for the remote IP address maps back to the very same IP address. .Pp If this option is set to .Dq no (the default) then only addresses and not host names may be used in .Pa ~/.ssh/known_hosts .Cm from and .Nm .Cm Match .Cm Host directives. .It Cm UseLogin Specifies whether .Xr login 1 is used for interactive login sessions. The default is .Dq no . Note that .Xr login 1 is never used for remote command execution. Note also, that if this is enabled, .Cm X11Forwarding will be disabled because .Xr login 1 does not know how to handle .Xr xauth 1 cookies. If .Cm UsePrivilegeSeparation is specified, it will be disabled after authentication. .It Cm UsePAM Enables the Pluggable Authentication Module interface. If set to .Dq yes this will enable PAM authentication using .Cm ChallengeResponseAuthentication and .Cm PasswordAuthentication in addition to PAM account and session module processing for all authentication types. .Pp Because PAM challenge-response authentication usually serves an equivalent role to password authentication, you should disable either .Cm PasswordAuthentication or .Cm ChallengeResponseAuthentication. .Pp If .Cm UsePAM is enabled, you will not be able to run .Xr sshd 8 as a non-root user. The default is .Dq no . .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 separates privileges by creating an unprivileged child process to deal with incoming network traffic. After successful authentication, another process will be created that has the privilege of the authenticated user. The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The argument must be .Dq yes , .Dq no , or .Dq sandbox . If .Cm UsePrivilegeSeparation is set to .Dq sandbox then the pre-authentication unprivileged process is subject to additional restrictions. The default is .Dq sandbox . .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is .Dq none . .It Cm X11DisplayOffset Specifies the first display number available for .Xr sshd 8 Ns 's X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be .Dq yes or .Dq no . The default is .Dq no . .Pp When X11 forwarding is enabled, there may be additional exposure to the server and to client displays if the .Xr sshd 8 proxy display is configured to listen on the wildcard address (see .Cm X11UseLocalhost below), though this is not the default. Additionally, the authentication spoofing and authentication data verification and substitution occur on the client side. The security risk of using X11 forwarding is that the client's X11 display server may be exposed to attack when the SSH client requests forwarding (see the warnings for .Cm ForwardX11 in .Xr ssh_config 5 ) . A system administrator may have a stance in which they want to protect clients that may expose themselves to attack by unwittingly requesting X11 forwarding, which can warrant a .Dq no setting. .Pp Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own forwarders. X11 forwarding is automatically disabled if .Cm UseLogin is enabled. .It Cm X11UseLocalhost Specifies whether .Xr sshd 8 should bind the X11 forwarding server to the loopback address or to the wildcard address. By default, sshd binds the forwarding server to the loopback address and sets the hostname part of the .Ev DISPLAY environment variable to .Dq localhost . This prevents remote hosts from connecting to the proxy display. However, some older X11 clients may not function with this configuration. .Cm X11UseLocalhost may be set to .Dq no to specify that the forwarding server should be bound to the wildcard address. The argument must be .Dq yes or .Dq no . The default is .Dq yes . .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 program, or .Dq none to not use one. The default is .Pa /usr/X11R6/bin/xauth . .El .Sh TIME FORMATS .Xr sshd 8 command-line arguments and configuration file options that specify time may be expressed using a sequence of the form: .Sm off .Ar time Op Ar qualifier , .Sm on where .Ar time is a positive integer value and .Ar qualifier is one of the following: .Pp .Bl -tag -width Ds -compact -offset indent .It Aq Cm none seconds .It Cm s | Cm S seconds .It Cm m | Cm M minutes .It Cm h | Cm H hours .It Cm d | Cm D days .It Cm w | Cm W weeks .El .Pp Each member of the sequence is added together to calculate the total time value. .Pp Time format examples: .Pp .Bl -tag -width Ds -compact -offset indent .It 600 600 seconds (10 minutes) .It 10m 10 minutes .It 1h30m 1 hour 30 minutes (90 minutes) .El .Sh FILES .Bl -tag -width Ds .It Pa /etc/ssh/sshd_config Contains configuration data for .Xr sshd 8 . This file should be writable by root only, but it is recommended (though not necessary) that it be world-readable. .El .Sh SEE ALSO .Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. openssh-7.2p2/ssherr.c010064400017500001750000000115311267006270000131250ustar00djmdjm/* $OpenBSD: ssherr.c,v 1.5 2015/09/13 14:39:16 tim Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 #include #include "ssherr.h" const char * ssh_err(int n) { switch (n) { case SSH_ERR_SUCCESS: return "success"; case SSH_ERR_INTERNAL_ERROR: return "unexpected internal error"; case SSH_ERR_ALLOC_FAIL: return "memory allocation failed"; case SSH_ERR_MESSAGE_INCOMPLETE: return "incomplete message"; case SSH_ERR_INVALID_FORMAT: return "invalid format"; case SSH_ERR_BIGNUM_IS_NEGATIVE: return "bignum is negative"; case SSH_ERR_STRING_TOO_LARGE: return "string is too large"; case SSH_ERR_BIGNUM_TOO_LARGE: return "bignum is too large"; case SSH_ERR_ECPOINT_TOO_LARGE: return "elliptic curve point is too large"; case SSH_ERR_NO_BUFFER_SPACE: return "insufficient buffer space"; case SSH_ERR_INVALID_ARGUMENT: return "invalid argument"; case SSH_ERR_KEY_BITS_MISMATCH: return "key bits do not match"; case SSH_ERR_EC_CURVE_INVALID: return "invalid elliptic curve"; case SSH_ERR_KEY_TYPE_MISMATCH: return "key type does not match"; case SSH_ERR_KEY_TYPE_UNKNOWN: return "unknown or unsupported key type"; case SSH_ERR_EC_CURVE_MISMATCH: return "elliptic curve does not match"; case SSH_ERR_EXPECTED_CERT: return "plain key provided where certificate required"; case SSH_ERR_KEY_LACKS_CERTBLOB: return "key lacks certificate data"; case SSH_ERR_KEY_CERT_UNKNOWN_TYPE: return "unknown/unsupported certificate type"; case SSH_ERR_KEY_CERT_INVALID_SIGN_KEY: return "invalid certificate signing key"; case SSH_ERR_KEY_INVALID_EC_VALUE: return "invalid elliptic curve value"; case SSH_ERR_SIGNATURE_INVALID: return "incorrect signature"; case SSH_ERR_LIBCRYPTO_ERROR: return "error in libcrypto"; /* XXX fetch and return */ case SSH_ERR_UNEXPECTED_TRAILING_DATA: return "unexpected bytes remain after decoding"; case SSH_ERR_SYSTEM_ERROR: return strerror(errno); case SSH_ERR_KEY_CERT_INVALID: return "invalid certificate"; case SSH_ERR_AGENT_COMMUNICATION: return "communication with agent failed"; case SSH_ERR_AGENT_FAILURE: return "agent refused operation"; case SSH_ERR_DH_GEX_OUT_OF_RANGE: return "DH GEX group out of range"; case SSH_ERR_DISCONNECTED: return "disconnected"; case SSH_ERR_MAC_INVALID: return "message authentication code incorrect"; case SSH_ERR_NO_CIPHER_ALG_MATCH: return "no matching cipher found"; case SSH_ERR_NO_MAC_ALG_MATCH: return "no matching MAC found"; case SSH_ERR_NO_COMPRESS_ALG_MATCH: return "no matching compression method found"; case SSH_ERR_NO_KEX_ALG_MATCH: return "no matching key exchange method found"; case SSH_ERR_NO_HOSTKEY_ALG_MATCH: return "no matching host key type found"; case SSH_ERR_PROTOCOL_MISMATCH: return "protocol version mismatch"; case SSH_ERR_NO_PROTOCOL_VERSION: return "could not read protocol version"; case SSH_ERR_NO_HOSTKEY_LOADED: return "could not load host key"; case SSH_ERR_NEED_REKEY: return "rekeying not supported by peer"; case SSH_ERR_PASSPHRASE_TOO_SHORT: return "passphrase is too short (minimum five characters)"; case SSH_ERR_FILE_CHANGED: return "file changed while reading"; case SSH_ERR_KEY_UNKNOWN_CIPHER: return "key encrypted using unsupported cipher"; case SSH_ERR_KEY_WRONG_PASSPHRASE: return "incorrect passphrase supplied to decrypt private key"; case SSH_ERR_KEY_BAD_PERMISSIONS: return "bad permissions"; case SSH_ERR_KEY_CERT_MISMATCH: return "certificate does not match key"; case SSH_ERR_KEY_NOT_FOUND: return "key not found"; case SSH_ERR_AGENT_NOT_PRESENT: return "agent not present"; case SSH_ERR_AGENT_NO_IDENTITIES: return "agent contains no identities"; case SSH_ERR_BUFFER_READ_ONLY: return "internal error: buffer is read-only"; case SSH_ERR_KRL_BAD_MAGIC: return "KRL file has invalid magic number"; case SSH_ERR_KEY_REVOKED: return "Key is revoked"; case SSH_ERR_CONN_CLOSED: return "Connection closed"; case SSH_ERR_CONN_TIMEOUT: return "Connection timed out"; case SSH_ERR_CONN_CORRUPT: return "Connection corrupted"; case SSH_ERR_PROTOCOL_ERROR: return "Protocol error"; default: return "unknown error"; } } openssh-7.2p2/ssherr.h010064400017500001750000000062621267006270000131370ustar00djmdjm/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND 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 _SSHERR_H #define _SSHERR_H /* XXX are these too granular? not granular enough? I can't decide - djm */ /* Error codes */ #define SSH_ERR_SUCCESS 0 #define SSH_ERR_INTERNAL_ERROR -1 #define SSH_ERR_ALLOC_FAIL -2 #define SSH_ERR_MESSAGE_INCOMPLETE -3 #define SSH_ERR_INVALID_FORMAT -4 #define SSH_ERR_BIGNUM_IS_NEGATIVE -5 #define SSH_ERR_STRING_TOO_LARGE -6 #define SSH_ERR_BIGNUM_TOO_LARGE -7 #define SSH_ERR_ECPOINT_TOO_LARGE -8 #define SSH_ERR_NO_BUFFER_SPACE -9 #define SSH_ERR_INVALID_ARGUMENT -10 #define SSH_ERR_KEY_BITS_MISMATCH -11 #define SSH_ERR_EC_CURVE_INVALID -12 #define SSH_ERR_KEY_TYPE_MISMATCH -13 #define SSH_ERR_KEY_TYPE_UNKNOWN -14 /* XXX UNSUPPORTED? */ #define SSH_ERR_EC_CURVE_MISMATCH -15 #define SSH_ERR_EXPECTED_CERT -16 #define SSH_ERR_KEY_LACKS_CERTBLOB -17 #define SSH_ERR_KEY_CERT_UNKNOWN_TYPE -18 #define SSH_ERR_KEY_CERT_INVALID_SIGN_KEY -19 #define SSH_ERR_KEY_INVALID_EC_VALUE -20 #define SSH_ERR_SIGNATURE_INVALID -21 #define SSH_ERR_LIBCRYPTO_ERROR -22 #define SSH_ERR_UNEXPECTED_TRAILING_DATA -23 #define SSH_ERR_SYSTEM_ERROR -24 #define SSH_ERR_KEY_CERT_INVALID -25 #define SSH_ERR_AGENT_COMMUNICATION -26 #define SSH_ERR_AGENT_FAILURE -27 #define SSH_ERR_DH_GEX_OUT_OF_RANGE -28 #define SSH_ERR_DISCONNECTED -29 #define SSH_ERR_MAC_INVALID -30 #define SSH_ERR_NO_CIPHER_ALG_MATCH -31 #define SSH_ERR_NO_MAC_ALG_MATCH -32 #define SSH_ERR_NO_COMPRESS_ALG_MATCH -33 #define SSH_ERR_NO_KEX_ALG_MATCH -34 #define SSH_ERR_NO_HOSTKEY_ALG_MATCH -35 #define SSH_ERR_NO_HOSTKEY_LOADED -36 #define SSH_ERR_PROTOCOL_MISMATCH -37 #define SSH_ERR_NO_PROTOCOL_VERSION -38 #define SSH_ERR_NEED_REKEY -39 #define SSH_ERR_PASSPHRASE_TOO_SHORT -40 #define SSH_ERR_FILE_CHANGED -41 #define SSH_ERR_KEY_UNKNOWN_CIPHER -42 #define SSH_ERR_KEY_WRONG_PASSPHRASE -43 #define SSH_ERR_KEY_BAD_PERMISSIONS -44 #define SSH_ERR_KEY_CERT_MISMATCH -45 #define SSH_ERR_KEY_NOT_FOUND -46 #define SSH_ERR_AGENT_NOT_PRESENT -47 #define SSH_ERR_AGENT_NO_IDENTITIES -48 #define SSH_ERR_BUFFER_READ_ONLY -49 #define SSH_ERR_KRL_BAD_MAGIC -50 #define SSH_ERR_KEY_REVOKED -51 #define SSH_ERR_CONN_CLOSED -52 #define SSH_ERR_CONN_TIMEOUT -53 #define SSH_ERR_CONN_CORRUPT -54 #define SSH_ERR_PROTOCOL_ERROR -55 /* Translate a numeric error code to a human-readable error string */ const char *ssh_err(int n); #endif /* _SSHERR_H */ openssh-7.2p2/sshkey.c010064400017500001750000003004451267006270000131320ustar00djmdjm/* $OpenBSD: sshkey.c,v 1.31 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. * Copyright (c) 2010,2011 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include /* MIN MAX */ #include #include #ifdef WITH_OPENSSL #include #include #include #endif #include "crypto_api.h" #include #include #include #include #include #ifdef HAVE_UTIL_H #include #endif /* HAVE_UTIL_H */ #include "ssh2.h" #include "ssherr.h" #include "misc.h" #include "sshbuf.h" #include "rsa.h" #include "cipher.h" #include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" /* openssh private key file format */ #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" #define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" #define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1) #define MARK_END_LEN (sizeof(MARK_END) - 1) #define KDFNAME "bcrypt" #define AUTH_MAGIC "openssh-key-v1" #define SALT_LEN 16 #define DEFAULT_CIPHERNAME "aes256-cbc" #define DEFAULT_ROUNDS 16 /* Version identification string for SSH v1 identity files. */ #define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" static int sshkey_from_blob_internal(struct sshbuf *buf, struct sshkey **keyp, int allow_cert); /* Supported key types */ struct keytype { const char *name; const char *shortname; int type; int nid; int cert; int sigonly; }; static const struct keytype keytypes[] = { { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 }, { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", KEY_ED25519_CERT, 0, 1, 0 }, #ifdef WITH_OPENSSL { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 }, # ifdef OPENSSL_HAS_ECC { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 }, # ifdef OPENSSL_HAS_NISTP521 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 }, # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 }, { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 }, # ifdef OPENSSL_HAS_ECC { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 }, { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", KEY_ECDSA_CERT, NID_secp384r1, 1, 0 }, # ifdef OPENSSL_HAS_NISTP521 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ { NULL, NULL, -1, -1, 0, 0 } }; const char * sshkey_type(const struct sshkey *k) { const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->type == k->type) return kt->shortname; } return "unknown"; } static const char * sshkey_ssh_name_from_type_nid(int type, int nid) { const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->type == type && (kt->nid == 0 || kt->nid == nid)) return kt->name; } return "ssh-unknown"; } int sshkey_type_is_cert(int type) { const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->type == type) return kt->cert; } return 0; } const char * sshkey_ssh_name(const struct sshkey *k) { return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid); } const char * sshkey_ssh_name_plain(const struct sshkey *k) { return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type), k->ecdsa_nid); } int sshkey_type_from_name(const char *name) { const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { /* Only allow shortname matches for plain key types */ if ((kt->name != NULL && strcmp(name, kt->name) == 0) || (!kt->cert && strcasecmp(kt->shortname, name) == 0)) return kt->type; } return KEY_UNSPEC; } int sshkey_ecdsa_nid_from_name(const char *name) { const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) continue; if (kt->name != NULL && strcmp(name, kt->name) == 0) return kt->nid; } return -1; } char * key_alg_list(int certs_only, int plain_only) { char *tmp, *ret = NULL; size_t nlen, rlen = 0; const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->name == NULL || kt->sigonly) continue; if ((certs_only && !kt->cert) || (plain_only && kt->cert)) continue; if (ret != NULL) ret[rlen++] = '\n'; nlen = strlen(kt->name); if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { free(ret); return NULL; } ret = tmp; memcpy(ret + rlen, kt->name, nlen + 1); rlen += nlen; } return ret; } int sshkey_names_valid2(const char *names, int allow_wildcard) { char *s, *cp, *p; const struct keytype *kt; int type; if (names == NULL || strcmp(names, "") == 0) return 0; if ((s = cp = strdup(names)) == NULL) return 0; for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { type = sshkey_type_from_name(p); if (type == KEY_RSA1) { free(s); return 0; } if (type == KEY_UNSPEC) { if (allow_wildcard) { /* * Try matching key types against the string. * If any has a positive or negative match then * the component is accepted. */ for (kt = keytypes; kt->type != -1; kt++) { if (kt->type == KEY_RSA1) continue; if (match_pattern_list(kt->name, p, 0) != 0) break; } if (kt->type != -1) continue; } free(s); return 0; } } free(s); return 1; } u_int sshkey_size(const struct sshkey *k) { switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: return BN_num_bits(k->rsa->n); case KEY_DSA: case KEY_DSA_CERT: return BN_num_bits(k->dsa->p); case KEY_ECDSA: case KEY_ECDSA_CERT: return sshkey_curve_nid_to_bits(k->ecdsa_nid); #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: return 256; /* XXX */ } return 0; } static int sshkey_type_is_valid_ca(int type) { switch (type) { case KEY_RSA: case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: return 1; default: return 0; } } int sshkey_is_cert(const struct sshkey *k) { if (k == NULL) return 0; return sshkey_type_is_cert(k->type); } /* Return the cert-less equivalent to a certified key type */ int sshkey_type_plain(int type) { switch (type) { case KEY_RSA_CERT: return KEY_RSA; case KEY_DSA_CERT: return KEY_DSA; case KEY_ECDSA_CERT: return KEY_ECDSA; case KEY_ED25519_CERT: return KEY_ED25519; default: return type; } } #ifdef WITH_OPENSSL /* XXX: these are really begging for a table-driven approach */ int sshkey_curve_name_to_nid(const char *name) { if (strcmp(name, "nistp256") == 0) return NID_X9_62_prime256v1; else if (strcmp(name, "nistp384") == 0) return NID_secp384r1; # ifdef OPENSSL_HAS_NISTP521 else if (strcmp(name, "nistp521") == 0) return NID_secp521r1; # endif /* OPENSSL_HAS_NISTP521 */ else return -1; } u_int sshkey_curve_nid_to_bits(int nid) { switch (nid) { case NID_X9_62_prime256v1: return 256; case NID_secp384r1: return 384; # ifdef OPENSSL_HAS_NISTP521 case NID_secp521r1: return 521; # endif /* OPENSSL_HAS_NISTP521 */ default: return 0; } } int sshkey_ecdsa_bits_to_nid(int bits) { switch (bits) { case 256: return NID_X9_62_prime256v1; case 384: return NID_secp384r1; # ifdef OPENSSL_HAS_NISTP521 case 521: return NID_secp521r1; # endif /* OPENSSL_HAS_NISTP521 */ default: return -1; } } const char * sshkey_curve_nid_to_name(int nid) { switch (nid) { case NID_X9_62_prime256v1: return "nistp256"; case NID_secp384r1: return "nistp384"; # ifdef OPENSSL_HAS_NISTP521 case NID_secp521r1: return "nistp521"; # endif /* OPENSSL_HAS_NISTP521 */ default: return NULL; } } int sshkey_ec_nid_to_hash_alg(int nid) { int kbits = sshkey_curve_nid_to_bits(nid); if (kbits <= 0) return -1; /* RFC5656 section 6.2.1 */ if (kbits <= 256) return SSH_DIGEST_SHA256; else if (kbits <= 384) return SSH_DIGEST_SHA384; else return SSH_DIGEST_SHA512; } #endif /* WITH_OPENSSL */ static void cert_free(struct sshkey_cert *cert) { u_int i; if (cert == NULL) return; sshbuf_free(cert->certblob); sshbuf_free(cert->critical); sshbuf_free(cert->extensions); free(cert->key_id); for (i = 0; i < cert->nprincipals; i++) free(cert->principals[i]); free(cert->principals); sshkey_free(cert->signature_key); explicit_bzero(cert, sizeof(*cert)); free(cert); } static struct sshkey_cert * cert_new(void) { struct sshkey_cert *cert; if ((cert = calloc(1, sizeof(*cert))) == NULL) return NULL; if ((cert->certblob = sshbuf_new()) == NULL || (cert->critical = sshbuf_new()) == NULL || (cert->extensions = sshbuf_new()) == NULL) { cert_free(cert); return NULL; } cert->key_id = NULL; cert->principals = NULL; cert->signature_key = NULL; return cert; } struct sshkey * sshkey_new(int type) { struct sshkey *k; #ifdef WITH_OPENSSL RSA *rsa; DSA *dsa; #endif /* WITH_OPENSSL */ if ((k = calloc(1, sizeof(*k))) == NULL) return NULL; k->type = type; k->ecdsa = NULL; k->ecdsa_nid = -1; k->dsa = NULL; k->rsa = NULL; k->cert = NULL; k->ed25519_sk = NULL; k->ed25519_pk = NULL; switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: if ((rsa = RSA_new()) == NULL || (rsa->n = BN_new()) == NULL || (rsa->e = BN_new()) == NULL) { if (rsa != NULL) RSA_free(rsa); free(k); return NULL; } k->rsa = rsa; break; case KEY_DSA: case KEY_DSA_CERT: if ((dsa = DSA_new()) == NULL || (dsa->p = BN_new()) == NULL || (dsa->q = BN_new()) == NULL || (dsa->g = BN_new()) == NULL || (dsa->pub_key = BN_new()) == NULL) { if (dsa != NULL) DSA_free(dsa); free(k); return NULL; } k->dsa = dsa; break; case KEY_ECDSA: case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ break; #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: /* no need to prealloc */ break; case KEY_UNSPEC: break; default: free(k); return NULL; break; } if (sshkey_is_cert(k)) { if ((k->cert = cert_new()) == NULL) { sshkey_free(k); return NULL; } } return k; } int sshkey_add_private(struct sshkey *k) { switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) if (bn_maybe_alloc_failed(k->rsa->d) || bn_maybe_alloc_failed(k->rsa->iqmp) || bn_maybe_alloc_failed(k->rsa->q) || bn_maybe_alloc_failed(k->rsa->p) || bn_maybe_alloc_failed(k->rsa->dmq1) || bn_maybe_alloc_failed(k->rsa->dmp1)) return SSH_ERR_ALLOC_FAIL; break; case KEY_DSA: case KEY_DSA_CERT: if (bn_maybe_alloc_failed(k->dsa->priv_key)) return SSH_ERR_ALLOC_FAIL; break; #undef bn_maybe_alloc_failed case KEY_ECDSA: case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ break; #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: /* no need to prealloc */ break; case KEY_UNSPEC: break; default: return SSH_ERR_INVALID_ARGUMENT; } return 0; } struct sshkey * sshkey_new_private(int type) { struct sshkey *k = sshkey_new(type); if (k == NULL) return NULL; if (sshkey_add_private(k) != 0) { sshkey_free(k); return NULL; } return k; } void sshkey_free(struct sshkey *k) { if (k == NULL) return; switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA: case KEY_RSA_CERT: if (k->rsa != NULL) RSA_free(k->rsa); k->rsa = NULL; break; case KEY_DSA: case KEY_DSA_CERT: if (k->dsa != NULL) DSA_free(k->dsa); k->dsa = NULL; break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: case KEY_ECDSA_CERT: if (k->ecdsa != NULL) EC_KEY_free(k->ecdsa); k->ecdsa = NULL; break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: if (k->ed25519_pk) { explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); free(k->ed25519_pk); k->ed25519_pk = NULL; } if (k->ed25519_sk) { explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); free(k->ed25519_sk); k->ed25519_sk = NULL; } break; case KEY_UNSPEC: break; default: break; } if (sshkey_is_cert(k)) cert_free(k->cert); explicit_bzero(k, sizeof(*k)); free(k); } static int cert_compare(struct sshkey_cert *a, struct sshkey_cert *b) { if (a == NULL && b == NULL) return 1; if (a == NULL || b == NULL) return 0; if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob)) return 0; if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob), sshbuf_len(a->certblob)) != 0) return 0; return 1; } /* * Compare public portions of key only, allowing comparisons between * certificates and plain keys too. */ int sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) { #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) BN_CTX *bnctx; #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ if (a == NULL || b == NULL || sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) return 0; switch (a->type) { #ifdef WITH_OPENSSL case KEY_RSA1: case KEY_RSA_CERT: case KEY_RSA: return a->rsa != NULL && b->rsa != NULL && BN_cmp(a->rsa->e, b->rsa->e) == 0 && BN_cmp(a->rsa->n, b->rsa->n) == 0; case KEY_DSA_CERT: case KEY_DSA: return a->dsa != NULL && b->dsa != NULL && BN_cmp(a->dsa->p, b->dsa->p) == 0 && BN_cmp(a->dsa->q, b->dsa->q) == 0 && BN_cmp(a->dsa->g, b->dsa->g) == 0 && BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: if (a->ecdsa == NULL || b->ecdsa == NULL || EC_KEY_get0_public_key(a->ecdsa) == NULL || EC_KEY_get0_public_key(b->ecdsa) == NULL) return 0; if ((bnctx = BN_CTX_new()) == NULL) return 0; if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), EC_KEY_get0_public_key(a->ecdsa), EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { BN_CTX_free(bnctx); return 0; } BN_CTX_free(bnctx); return 1; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: return a->ed25519_pk != NULL && b->ed25519_pk != NULL && memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; default: return 0; } /* NOTREACHED */ } int sshkey_equal(const struct sshkey *a, const struct sshkey *b) { if (a == NULL || b == NULL || a->type != b->type) return 0; if (sshkey_is_cert(a)) { if (!cert_compare(a->cert, b->cert)) return 0; } return sshkey_equal_public(a, b); } static int to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain) { int type, ret = SSH_ERR_INTERNAL_ERROR; const char *typename; if (key == NULL) return SSH_ERR_INVALID_ARGUMENT; if (sshkey_is_cert(key)) { if (key->cert == NULL) return SSH_ERR_EXPECTED_CERT; if (sshbuf_len(key->cert->certblob) == 0) return SSH_ERR_KEY_LACKS_CERTBLOB; } type = force_plain ? sshkey_type_plain(key->type) : key->type; typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid); switch (type) { #ifdef WITH_OPENSSL case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_RSA_CERT: #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: /* Use the existing blob */ /* XXX modified flag? */ if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0) return ret; break; #ifdef WITH_OPENSSL case KEY_DSA: if (key->dsa == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((ret = sshbuf_put_cstring(b, typename)) != 0 || (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) return ret; break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (key->ecdsa == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((ret = sshbuf_put_cstring(b, typename)) != 0 || (ret = sshbuf_put_cstring(b, sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) return ret; break; # endif case KEY_RSA: if (key->rsa == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((ret = sshbuf_put_cstring(b, typename)) != 0 || (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) return ret; break; #endif /* WITH_OPENSSL */ case KEY_ED25519: if (key->ed25519_pk == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((ret = sshbuf_put_cstring(b, typename)) != 0 || (ret = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0) return ret; break; default: return SSH_ERR_KEY_TYPE_UNKNOWN; } return 0; } int sshkey_putb(const struct sshkey *key, struct sshbuf *b) { return to_blob_buf(key, b, 0); } int sshkey_puts(const struct sshkey *key, struct sshbuf *b) { struct sshbuf *tmp; int r; if ((tmp = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; r = to_blob_buf(key, tmp, 0); if (r == 0) r = sshbuf_put_stringb(b, tmp); sshbuf_free(tmp); return r; } int sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) { return to_blob_buf(key, b, 1); } static int to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain) { int ret = SSH_ERR_INTERNAL_ERROR; size_t len; struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; if (blobp != NULL) *blobp = NULL; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((ret = to_blob_buf(key, b, force_plain)) != 0) goto out; len = sshbuf_len(b); if (lenp != NULL) *lenp = len; if (blobp != NULL) { if ((*blobp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } memcpy(*blobp, sshbuf_ptr(b), len); } ret = 0; out: sshbuf_free(b); return ret; } int sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) { return to_blob(key, blobp, lenp, 0); } int sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) { return to_blob(key, blobp, lenp, 1); } int sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, u_char **retp, size_t *lenp) { u_char *blob = NULL, *ret = NULL; size_t blob_len = 0; int r = SSH_ERR_INTERNAL_ERROR; if (retp != NULL) *retp = NULL; if (lenp != NULL) *lenp = 0; if (ssh_digest_bytes(dgst_alg) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if (k->type == KEY_RSA1) { #ifdef WITH_OPENSSL int nlen = BN_num_bytes(k->rsa->n); int elen = BN_num_bytes(k->rsa->e); blob_len = nlen + elen; if (nlen >= INT_MAX - elen || (blob = malloc(blob_len)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } BN_bn2bin(k->rsa->n, blob); BN_bn2bin(k->rsa->e, blob + nlen); #endif /* WITH_OPENSSL */ } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) goto out; if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, ret, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; /* success */ if (retp != NULL) { *retp = ret; ret = NULL; } if (lenp != NULL) *lenp = ssh_digest_bytes(dgst_alg); r = 0; out: free(ret); if (blob != NULL) { explicit_bzero(blob, blob_len); free(blob); } return r; } static char * fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) { char *ret; size_t plen = strlen(alg) + 1; size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; int r; if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) return NULL; strlcpy(ret, alg, rlen); strlcat(ret, ":", rlen); if (dgst_raw_len == 0) return ret; if ((r = b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen)) == -1) { explicit_bzero(ret, rlen); free(ret); return NULL; } /* Trim padding characters from end */ ret[strcspn(ret, "=")] = '\0'; return ret; } static char * fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) { char *retval, hex[5]; size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) return NULL; strlcpy(retval, alg, rlen); strlcat(retval, ":", rlen); for (i = 0; i < dgst_raw_len; i++) { snprintf(hex, sizeof(hex), "%s%02x", i > 0 ? ":" : "", dgst_raw[i]); strlcat(retval, hex, rlen); } return retval; } static char * fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) { char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; u_int i, j = 0, rounds, seed = 1; char *retval; rounds = (dgst_raw_len / 2) + 1; if ((retval = calloc(rounds, 6)) == NULL) return NULL; retval[j++] = 'x'; for (i = 0; i < rounds; i++) { u_int idx0, idx1, idx2, idx3, idx4; if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + seed) % 6; idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + (seed / 6)) % 6; retval[j++] = vowels[idx0]; retval[j++] = consonants[idx1]; retval[j++] = vowels[idx2]; if ((i + 1) < rounds) { idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; retval[j++] = consonants[idx3]; retval[j++] = '-'; retval[j++] = consonants[idx4]; seed = ((seed * 5) + ((((u_int)(dgst_raw[2 * i])) * 7) + ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; } } else { idx0 = seed % 6; idx1 = 16; idx2 = seed / 6; retval[j++] = vowels[idx0]; retval[j++] = consonants[idx1]; retval[j++] = vowels[idx2]; } } retval[j++] = 'x'; retval[j++] = '\0'; return retval; } /* * Draw an ASCII-Art representing the fingerprint so human brain can * profit from its built-in pattern recognition ability. * This technique is called "random art" and can be found in some * scientific publications like this original paper: * * "Hash Visualization: a New Technique to improve Real-World Security", * Perrig A. and Song D., 1999, International Workshop on Cryptographic * Techniques and E-Commerce (CrypTEC '99) * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf * * The subject came up in a talk by Dan Kaminsky, too. * * If you see the picture is different, the key is different. * If the picture looks the same, you still know nothing. * * The algorithm used here is a worm crawling over a discrete plane, * leaving a trace (augmenting the field) everywhere it goes. * Movement is taken from dgst_raw 2bit-wise. Bumping into walls * makes the respective movement vector be ignored for this turn. * Graphs are not unambiguous, because circles in graphs can be * walked in either direction. */ /* * Field sizes for the random art. Have to be odd, so the starting point * can be in the exact middle of the picture, and FLDBASE should be >=8 . * Else pictures would be too dense, and drawing the frame would * fail, too, because the key type would not fit in anymore. */ #define FLDBASE 8 #define FLDSIZE_Y (FLDBASE + 1) #define FLDSIZE_X (FLDBASE * 2 + 1) static char * fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, const struct sshkey *k) { /* * Chars to be used after each other every time the worm * intersects with itself. Matter of taste. */ char *augmentation_string = " .o+=*BOX@%&#/^SE"; char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; u_char field[FLDSIZE_X][FLDSIZE_Y]; size_t i, tlen, hlen; u_int b; int x, y, r; size_t len = strlen(augmentation_string) - 1; if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL) return NULL; /* initialize field */ memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); x = FLDSIZE_X / 2; y = FLDSIZE_Y / 2; /* process raw key */ for (i = 0; i < dgst_raw_len; i++) { int input; /* each byte conveys four 2-bit move commands */ input = dgst_raw[i]; for (b = 0; b < 4; b++) { /* evaluate 2 bit, rest is shifted later */ x += (input & 0x1) ? 1 : -1; y += (input & 0x2) ? 1 : -1; /* assure we are still in bounds */ x = MAX(x, 0); y = MAX(y, 0); x = MIN(x, FLDSIZE_X - 1); y = MIN(y, FLDSIZE_Y - 1); /* augment the field */ if (field[x][y] < len - 2) field[x][y]++; input = input >> 2; } } /* mark starting point and end point*/ field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; field[x][y] = len; /* assemble title */ r = snprintf(title, sizeof(title), "[%s %u]", sshkey_type(k), sshkey_size(k)); /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ if (r < 0 || r > (int)sizeof(title)) r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); tlen = (r <= 0) ? 0 : strlen(title); /* assemble hash ID. */ r = snprintf(hash, sizeof(hash), "[%s]", alg); hlen = (r <= 0) ? 0 : strlen(hash); /* output upper border */ p = retval; *p++ = '+'; for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++) *p++ = '-'; memcpy(p, title, tlen); p += tlen; for (i += tlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; *p++ = '\n'; /* output content */ for (y = 0; y < FLDSIZE_Y; y++) { *p++ = '|'; for (x = 0; x < FLDSIZE_X; x++) *p++ = augmentation_string[MIN(field[x][y], len)]; *p++ = '|'; *p++ = '\n'; } /* output lower border */ *p++ = '+'; for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) *p++ = '-'; memcpy(p, hash, hlen); p += hlen; for (i += hlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; return retval; } char * sshkey_fingerprint(const struct sshkey *k, int dgst_alg, enum sshkey_fp_rep dgst_rep) { char *retval = NULL; u_char *dgst_raw; size_t dgst_raw_len; if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) return NULL; switch (dgst_rep) { case SSH_FP_DEFAULT: if (dgst_alg == SSH_DIGEST_MD5) { retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), dgst_raw, dgst_raw_len); } else { retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), dgst_raw, dgst_raw_len); } break; case SSH_FP_HEX: retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), dgst_raw, dgst_raw_len); break; case SSH_FP_BASE64: retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), dgst_raw, dgst_raw_len); break; case SSH_FP_BUBBLEBABBLE: retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); break; case SSH_FP_RANDOMART: retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), dgst_raw, dgst_raw_len, k); break; default: explicit_bzero(dgst_raw, dgst_raw_len); free(dgst_raw); return NULL; } explicit_bzero(dgst_raw, dgst_raw_len); free(dgst_raw); return retval; } #ifdef WITH_SSH1 /* * Reads a multiple-precision integer in decimal from the buffer, and advances * the pointer. The integer must already be initialized. This function is * permitted to modify the buffer. This leaves *cpp to point just beyond the * last processed character. */ static int read_decimal_bignum(char **cpp, BIGNUM *v) { char *cp; size_t e; int skip = 1; /* skip white space */ cp = *cpp; while (*cp == ' ' || *cp == '\t') cp++; e = strspn(cp, "0123456789"); if (e == 0) return SSH_ERR_INVALID_FORMAT; if (e > SSHBUF_MAX_BIGNUM * 3) return SSH_ERR_BIGNUM_TOO_LARGE; if (cp[e] == '\0') skip = 0; else if (strchr(" \t\r\n", cp[e]) == NULL) return SSH_ERR_INVALID_FORMAT; cp[e] = '\0'; if (BN_dec2bn(&v, cp) <= 0) return SSH_ERR_INVALID_FORMAT; *cpp = cp + e + skip; return 0; } #endif /* WITH_SSH1 */ /* returns 0 ok, and < 0 error */ int sshkey_read(struct sshkey *ret, char **cpp) { struct sshkey *k; int retval = SSH_ERR_INVALID_FORMAT; char *ep, *cp, *space; int r, type, curve_nid = -1; struct sshbuf *blob; #ifdef WITH_SSH1 u_long bits; #endif /* WITH_SSH1 */ cp = *cpp; switch (ret->type) { case KEY_RSA1: #ifdef WITH_SSH1 /* Get number of bits. */ bits = strtoul(cp, &ep, 10); if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL || bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ /* Get public exponent, public modulus. */ if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) return r; if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) return r; /* validate the claimed number of bits */ if (BN_num_bits(ret->rsa->n) != (int)bits) return SSH_ERR_KEY_BITS_MISMATCH; *cpp = ep; retval = 0; #endif /* WITH_SSH1 */ break; case KEY_UNSPEC: case KEY_RSA: case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_RSA_CERT: case KEY_ED25519_CERT: space = strchr(cp, ' '); if (space == NULL) return SSH_ERR_INVALID_FORMAT; *space = '\0'; type = sshkey_type_from_name(cp); if (sshkey_type_plain(type) == KEY_ECDSA && (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1) return SSH_ERR_EC_CURVE_INVALID; *space = ' '; if (type == KEY_UNSPEC) return SSH_ERR_INVALID_FORMAT; cp = space+1; if (*cp == '\0') return SSH_ERR_INVALID_FORMAT; if (ret->type != KEY_UNSPEC && ret->type != type) return SSH_ERR_KEY_TYPE_MISMATCH; if ((blob = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* trim comment */ space = strchr(cp, ' '); if (space) { /* advance 'space': skip whitespace */ *space++ = '\0'; while (*space == ' ' || *space == '\t') space++; ep = space; } else ep = cp + strlen(cp); if ((r = sshbuf_b64tod(blob, cp)) != 0) { sshbuf_free(blob); return r; } if ((r = sshkey_from_blob(sshbuf_ptr(blob), sshbuf_len(blob), &k)) != 0) { sshbuf_free(blob); return r; } sshbuf_free(blob); if (k->type != type) { sshkey_free(k); return SSH_ERR_KEY_TYPE_MISMATCH; } if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) { sshkey_free(k); return SSH_ERR_EC_CURVE_MISMATCH; } ret->type = type; if (sshkey_is_cert(ret)) { if (!sshkey_is_cert(k)) { sshkey_free(k); return SSH_ERR_EXPECTED_CERT; } if (ret->cert != NULL) cert_free(ret->cert); ret->cert = k->cert; k->cert = NULL; } switch (sshkey_type_plain(ret->type)) { #ifdef WITH_OPENSSL case KEY_RSA: if (ret->rsa != NULL) RSA_free(ret->rsa); ret->rsa = k->rsa; k->rsa = NULL; #ifdef DEBUG_PK RSA_print_fp(stderr, ret->rsa, 8); #endif break; case KEY_DSA: if (ret->dsa != NULL) DSA_free(ret->dsa); ret->dsa = k->dsa; k->dsa = NULL; #ifdef DEBUG_PK DSA_print_fp(stderr, ret->dsa, 8); #endif break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (ret->ecdsa != NULL) EC_KEY_free(ret->ecdsa); ret->ecdsa = k->ecdsa; ret->ecdsa_nid = k->ecdsa_nid; k->ecdsa = NULL; k->ecdsa_nid = -1; #ifdef DEBUG_PK sshkey_dump_ec_key(ret->ecdsa); #endif break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519: free(ret->ed25519_pk); ret->ed25519_pk = k->ed25519_pk; k->ed25519_pk = NULL; #ifdef DEBUG_PK /* XXX */ #endif break; } *cpp = ep; retval = 0; /*XXXX*/ sshkey_free(k); if (retval != 0) break; break; default: return SSH_ERR_INVALID_ARGUMENT; } return retval; } int sshkey_to_base64(const struct sshkey *key, char **b64p) { int r = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; char *uu = NULL; if (b64p != NULL) *b64p = NULL; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_putb(key, b)) != 0) goto out; if ((uu = sshbuf_dtob64(b)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* Success */ if (b64p != NULL) { *b64p = uu; uu = NULL; } r = 0; out: sshbuf_free(b); free(uu); return r; } static int sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b) { int r = SSH_ERR_INTERNAL_ERROR; #ifdef WITH_SSH1 u_int bits = 0; char *dec_e = NULL, *dec_n = NULL; if (key->rsa == NULL || key->rsa->e == NULL || key->rsa->n == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* size of modulus 'n' */ if ((bits = BN_num_bits(key->rsa->n)) <= 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0) goto out; /* Success */ r = 0; out: if (dec_e != NULL) OPENSSL_free(dec_e); if (dec_n != NULL) OPENSSL_free(dec_n); #endif /* WITH_SSH1 */ return r; } static int sshkey_format_text(const struct sshkey *key, struct sshbuf *b) { int r = SSH_ERR_INTERNAL_ERROR; char *uu = NULL; if (key->type == KEY_RSA1) { if ((r = sshkey_format_rsa1(key, b)) != 0) goto out; } else { /* Unsupported key types handled in sshkey_to_base64() */ if ((r = sshkey_to_base64(key, &uu)) != 0) goto out; if ((r = sshbuf_putf(b, "%s %s", sshkey_ssh_name(key), uu)) != 0) goto out; } r = 0; out: free(uu); return r; } int sshkey_write(const struct sshkey *key, FILE *f) { struct sshbuf *b = NULL; int r = SSH_ERR_INTERNAL_ERROR; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_format_text(key, b)) != 0) goto out; if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) { if (feof(f)) errno = EPIPE; r = SSH_ERR_SYSTEM_ERROR; goto out; } /* Success */ r = 0; out: sshbuf_free(b); return r; } const char * sshkey_cert_type(const struct sshkey *k) { switch (k->cert->type) { case SSH2_CERT_TYPE_USER: return "user"; case SSH2_CERT_TYPE_HOST: return "host"; default: return "unknown"; } } #ifdef WITH_OPENSSL static int rsa_generate_private_key(u_int bits, RSA **rsap) { RSA *private = NULL; BIGNUM *f4 = NULL; int ret = SSH_ERR_INTERNAL_ERROR; if (rsap == NULL || bits < SSH_RSA_MINIMUM_MODULUS_SIZE || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_INVALID_ARGUMENT; *rsap = NULL; if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } *rsap = private; private = NULL; ret = 0; out: if (private != NULL) RSA_free(private); if (f4 != NULL) BN_free(f4); return ret; } static int dsa_generate_private_key(u_int bits, DSA **dsap) { DSA *private; int ret = SSH_ERR_INTERNAL_ERROR; if (dsap == NULL || bits != 1024) return SSH_ERR_INVALID_ARGUMENT; if ((private = DSA_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } *dsap = NULL; if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, NULL, NULL) || !DSA_generate_key(private)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } *dsap = private; private = NULL; ret = 0; out: if (private != NULL) DSA_free(private); return ret; } # ifdef OPENSSL_HAS_ECC int sshkey_ecdsa_key_to_nid(EC_KEY *k) { EC_GROUP *eg; int nids[] = { NID_X9_62_prime256v1, NID_secp384r1, # ifdef OPENSSL_HAS_NISTP521 NID_secp521r1, # endif /* OPENSSL_HAS_NISTP521 */ -1 }; int nid; u_int i; BN_CTX *bnctx; const EC_GROUP *g = EC_KEY_get0_group(k); /* * The group may be stored in a ASN.1 encoded private key in one of two * ways: as a "named group", which is reconstituted by ASN.1 object ID * or explicit group parameters encoded into the key blob. Only the * "named group" case sets the group NID for us, but we can figure * it out for the other case by comparing against all the groups that * are supported. */ if ((nid = EC_GROUP_get_curve_name(g)) > 0) return nid; if ((bnctx = BN_CTX_new()) == NULL) return -1; for (i = 0; nids[i] != -1; i++) { if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) { BN_CTX_free(bnctx); return -1; } if (EC_GROUP_cmp(g, eg, bnctx) == 0) break; EC_GROUP_free(eg); } BN_CTX_free(bnctx); if (nids[i] != -1) { /* Use the group with the NID attached */ EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(k, eg) != 1) { EC_GROUP_free(eg); return -1; } } return nids[i]; } static int ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) { EC_KEY *private; int ret = SSH_ERR_INTERNAL_ERROR; if (nid == NULL || ecdsap == NULL || (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) return SSH_ERR_INVALID_ARGUMENT; *ecdsap = NULL; if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (EC_KEY_generate_key(private) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); *ecdsap = private; private = NULL; ret = 0; out: if (private != NULL) EC_KEY_free(private); return ret; } # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ int sshkey_generate(int type, u_int bits, struct sshkey **keyp) { struct sshkey *k; int ret = SSH_ERR_INTERNAL_ERROR; if (keyp == NULL) return SSH_ERR_INVALID_ARGUMENT; *keyp = NULL; if ((k = sshkey_new(KEY_UNSPEC)) == NULL) return SSH_ERR_ALLOC_FAIL; switch (type) { case KEY_ED25519: if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL || (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; break; } crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); ret = 0; break; #ifdef WITH_OPENSSL case KEY_DSA: ret = dsa_generate_private_key(bits, &k->dsa); break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, &k->ecdsa); break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: case KEY_RSA1: ret = rsa_generate_private_key(bits, &k->rsa); break; #endif /* WITH_OPENSSL */ default: ret = SSH_ERR_INVALID_ARGUMENT; } if (ret == 0) { k->type = type; *keyp = k; } else sshkey_free(k); return ret; } int sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key) { u_int i; const struct sshkey_cert *from; struct sshkey_cert *to; int ret = SSH_ERR_INTERNAL_ERROR; if (to_key->cert != NULL) { cert_free(to_key->cert); to_key->cert = NULL; } if ((from = from_key->cert) == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((to = to_key->cert = cert_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 || (ret = sshbuf_putb(to->critical, from->critical)) != 0 || (ret = sshbuf_putb(to->extensions, from->extensions)) != 0) return ret; to->serial = from->serial; to->type = from->type; if (from->key_id == NULL) to->key_id = NULL; else if ((to->key_id = strdup(from->key_id)) == NULL) return SSH_ERR_ALLOC_FAIL; to->valid_after = from->valid_after; to->valid_before = from->valid_before; if (from->signature_key == NULL) to->signature_key = NULL; else if ((ret = sshkey_from_private(from->signature_key, &to->signature_key)) != 0) return ret; if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) return SSH_ERR_INVALID_ARGUMENT; if (from->nprincipals > 0) { if ((to->principals = calloc(from->nprincipals, sizeof(*to->principals))) == NULL) return SSH_ERR_ALLOC_FAIL; for (i = 0; i < from->nprincipals; i++) { to->principals[i] = strdup(from->principals[i]); if (to->principals[i] == NULL) { to->nprincipals = i; return SSH_ERR_ALLOC_FAIL; } } } to->nprincipals = from->nprincipals; return 0; } int sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) { struct sshkey *n = NULL; int ret = SSH_ERR_INTERNAL_ERROR; *pkp = NULL; switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA: case KEY_DSA_CERT: if ((n = sshkey_new(k->type)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || (BN_copy(n->dsa->q, k->dsa->q) == NULL) || (BN_copy(n->dsa->g, k->dsa->g) == NULL) || (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { sshkey_free(n); return SSH_ERR_ALLOC_FAIL; } break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: case KEY_ECDSA_CERT: if ((n = sshkey_new(k->type)) == NULL) return SSH_ERR_ALLOC_FAIL; n->ecdsa_nid = k->ecdsa_nid; n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); if (n->ecdsa == NULL) { sshkey_free(n); return SSH_ERR_ALLOC_FAIL; } if (EC_KEY_set_public_key(n->ecdsa, EC_KEY_get0_public_key(k->ecdsa)) != 1) { sshkey_free(n); return SSH_ERR_LIBCRYPTO_ERROR; } break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: case KEY_RSA1: case KEY_RSA_CERT: if ((n = sshkey_new(k->type)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { sshkey_free(n); return SSH_ERR_ALLOC_FAIL; } break; #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: if ((n = sshkey_new(k->type)) == NULL) return SSH_ERR_ALLOC_FAIL; if (k->ed25519_pk != NULL) { if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { sshkey_free(n); return SSH_ERR_ALLOC_FAIL; } memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); } break; default: return SSH_ERR_KEY_TYPE_UNKNOWN; } if (sshkey_is_cert(k)) { if ((ret = sshkey_cert_copy(k, n)) != 0) { sshkey_free(n); return ret; } } *pkp = n; return 0; } static int cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) { struct sshbuf *principals = NULL, *crit = NULL; struct sshbuf *exts = NULL, *ca = NULL; u_char *sig = NULL; size_t signed_len = 0, slen = 0, kidlen = 0; int ret = SSH_ERR_INTERNAL_ERROR; /* Copy the entire key blob for verification and later serialisation */ if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0) return ret; /* Parse body of certificate up to signature */ if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 || (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || (ret = sshbuf_froms(b, &principals)) != 0 || (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || (ret = sshbuf_froms(b, &crit)) != 0 || (ret = sshbuf_froms(b, &exts)) != 0 || (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || (ret = sshbuf_froms(b, &ca)) != 0) { /* XXX debug print error for ret */ ret = SSH_ERR_INVALID_FORMAT; goto out; } /* Signature is left in the buffer so we can calculate this length */ signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b); if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (key->cert->type != SSH2_CERT_TYPE_USER && key->cert->type != SSH2_CERT_TYPE_HOST) { ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE; goto out; } /* Parse principals section */ while (sshbuf_len(principals) > 0) { char *principal = NULL; char **oprincipals = NULL; if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if ((ret = sshbuf_get_cstring(principals, &principal, NULL)) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } oprincipals = key->cert->principals; key->cert->principals = reallocarray(key->cert->principals, key->cert->nprincipals + 1, sizeof(*key->cert->principals)); if (key->cert->principals == NULL) { free(principal); key->cert->principals = oprincipals; ret = SSH_ERR_ALLOC_FAIL; goto out; } key->cert->principals[key->cert->nprincipals++] = principal; } /* * Stash a copies of the critical options and extensions sections * for later use. */ if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 || (exts != NULL && (ret = sshbuf_putb(key->cert->extensions, exts)) != 0)) goto out; /* * Validate critical options and extensions sections format. */ while (sshbuf_len(crit) != 0) { if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 || (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) { sshbuf_reset(key->cert->critical); ret = SSH_ERR_INVALID_FORMAT; goto out; } } while (exts != NULL && sshbuf_len(exts) != 0) { if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 || (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) { sshbuf_reset(key->cert->extensions); ret = SSH_ERR_INVALID_FORMAT; goto out; } } /* Parse CA key and check signature */ if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) { ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; } if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) { ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; } if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) goto out; /* Success */ ret = 0; out: sshbuf_free(ca); sshbuf_free(crit); sshbuf_free(exts); sshbuf_free(principals); free(sig); return ret; } static int sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, int allow_cert) { int type, ret = SSH_ERR_INTERNAL_ERROR; char *ktype = NULL, *curve = NULL; struct sshkey *key = NULL; size_t len; u_char *pk = NULL; struct sshbuf *copy; #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) EC_POINT *q = NULL; #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ #ifdef DEBUG_PK /* XXX */ sshbuf_dump(b, stderr); #endif *keyp = NULL; if ((copy = sshbuf_fromb(b)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } type = sshkey_type_from_name(ktype); if (!allow_cert && sshkey_type_is_cert(type)) { ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; } switch (type) { #ifdef WITH_OPENSSL case KEY_RSA_CERT: /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } /* FALLTHROUGH */ case KEY_RSA: if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || sshbuf_get_bignum2(b, key->rsa->n) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } #ifdef DEBUG_PK RSA_print_fp(stderr, key->rsa, 8); #endif break; case KEY_DSA_CERT: /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } /* FALLTHROUGH */ case KEY_DSA: if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || sshbuf_get_bignum2(b, key->dsa->q) != 0 || sshbuf_get_bignum2(b, key->dsa->g) != 0 || sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } #ifdef DEBUG_PK DSA_print_fp(stderr, key->dsa, 8); #endif break; case KEY_ECDSA_CERT: /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } /* FALLTHROUGH */ # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype); if (sshbuf_get_cstring(b, &curve, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { ret = SSH_ERR_EC_CURVE_MISMATCH; goto out; } if (key->ecdsa != NULL) EC_KEY_free(key->ecdsa); if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { ret = SSH_ERR_EC_CURVE_INVALID; goto out; } if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) { ret = SSH_ERR_KEY_INVALID_EC_VALUE; goto out; } if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { /* XXX assume it is a allocation error */ ret = SSH_ERR_ALLOC_FAIL; goto out; } #ifdef DEBUG_PK sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); #endif break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } /* FALLTHROUGH */ case KEY_ED25519: if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) goto out; if (len != ED25519_PK_SZ) { ret = SSH_ERR_INVALID_FORMAT; goto out; } if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } key->ed25519_pk = pk; pk = NULL; break; case KEY_UNSPEC: if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } break; default: ret = SSH_ERR_KEY_TYPE_UNKNOWN; goto out; } /* Parse certificate potion */ if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0) goto out; if (key != NULL && sshbuf_len(b) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } ret = 0; *keyp = key; key = NULL; out: sshbuf_free(copy); sshkey_free(key); free(ktype); free(curve); free(pk); #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) if (q != NULL) EC_POINT_free(q); #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ return ret; } int sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) { struct sshbuf *b; int r; if ((b = sshbuf_from(blob, blen)) == NULL) return SSH_ERR_ALLOC_FAIL; r = sshkey_from_blob_internal(b, keyp, 1); sshbuf_free(b); return r; } int sshkey_fromb(struct sshbuf *b, struct sshkey **keyp) { return sshkey_from_blob_internal(b, keyp, 1); } int sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) { struct sshbuf *b; int r; if ((r = sshbuf_froms(buf, &b)) != 0) return r; r = sshkey_from_blob_internal(b, keyp, 1); sshbuf_free(b); return r; } int sshkey_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *alg, u_int compat) { if (sigp != NULL) *sigp = NULL; if (lenp != NULL) *lenp = 0; if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; switch (key->type) { #ifdef WITH_OPENSSL case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_sign(key, sigp, lenp, data, datalen, compat); # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); # endif /* OPENSSL_HAS_ECC */ case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg); #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); default: return SSH_ERR_KEY_TYPE_UNKNOWN; } } /* * ssh_key_verify returns 0 for a correct signature and < 0 on error. */ int sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t dlen, u_int compat) { if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; switch (key->type) { #ifdef WITH_OPENSSL case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_verify(key, sig, siglen, data, dlen, compat); # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); # endif /* OPENSSL_HAS_ECC */ case KEY_RSA_CERT: case KEY_RSA: return ssh_rsa_verify(key, sig, siglen, data, dlen); #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); default: return SSH_ERR_KEY_TYPE_UNKNOWN; } } /* Converts a private to a public key */ int sshkey_demote(const struct sshkey *k, struct sshkey **dkp) { struct sshkey *pk; int ret = SSH_ERR_INTERNAL_ERROR; *dkp = NULL; if ((pk = calloc(1, sizeof(*pk))) == NULL) return SSH_ERR_ALLOC_FAIL; pk->type = k->type; pk->flags = k->flags; pk->ecdsa_nid = k->ecdsa_nid; pk->dsa = NULL; pk->ecdsa = NULL; pk->rsa = NULL; pk->ed25519_pk = NULL; pk->ed25519_sk = NULL; switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA_CERT: if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ case KEY_RSA1: case KEY_RSA: if ((pk->rsa = RSA_new()) == NULL || (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto fail; } break; case KEY_DSA_CERT: if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ case KEY_DSA: if ((pk->dsa = DSA_new()) == NULL || (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto fail; } break; case KEY_ECDSA_CERT: if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid); if (pk->ecdsa == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto fail; } if (EC_KEY_set_public_key(pk->ecdsa, EC_KEY_get0_public_key(k->ecdsa)) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto fail; } break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ case KEY_ED25519: if (k->ed25519_pk != NULL) { if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto fail; } memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); } break; default: ret = SSH_ERR_KEY_TYPE_UNKNOWN; fail: sshkey_free(pk); return ret; } *dkp = pk; return 0; } /* Convert a plain key to their _CERT equivalent */ int sshkey_to_certified(struct sshkey *k) { int newtype; switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA: newtype = KEY_RSA_CERT; break; case KEY_DSA: newtype = KEY_DSA_CERT; break; case KEY_ECDSA: newtype = KEY_ECDSA_CERT; break; #endif /* WITH_OPENSSL */ case KEY_ED25519: newtype = KEY_ED25519_CERT; break; default: return SSH_ERR_INVALID_ARGUMENT; } if ((k->cert = cert_new()) == NULL) return SSH_ERR_ALLOC_FAIL; k->type = newtype; return 0; } /* Convert a certificate to its raw key equivalent */ int sshkey_drop_cert(struct sshkey *k) { if (!sshkey_type_is_cert(k->type)) return SSH_ERR_KEY_TYPE_UNKNOWN; cert_free(k->cert); k->cert = NULL; k->type = sshkey_type_plain(k->type); return 0; } /* Sign a certified key, (re-)generating the signed certblob. */ int sshkey_certify(struct sshkey *k, struct sshkey *ca) { struct sshbuf *principals = NULL; u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; size_t i, ca_len, sig_len; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *cert; if (k == NULL || k->cert == NULL || k->cert->certblob == NULL || ca == NULL) return SSH_ERR_INVALID_ARGUMENT; if (!sshkey_is_cert(k)) return SSH_ERR_KEY_TYPE_UNKNOWN; if (!sshkey_type_is_valid_ca(ca->type)) return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; cert = k->cert->certblob; /* for readability */ sshbuf_reset(cert); if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0) goto out; /* -v01 certs put nonce first */ arc4random_buf(&nonce, sizeof(nonce)); if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0) goto out; /* XXX this substantially duplicates to_blob(); refactor */ switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA_CERT: if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) goto out; break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: if ((ret = sshbuf_put_cstring(cert, sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || (ret = sshbuf_put_ec(cert, EC_KEY_get0_public_key(k->ecdsa), EC_KEY_get0_group(k->ecdsa))) != 0) goto out; break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA_CERT: if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) goto out; break; #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: if ((ret = sshbuf_put_string(cert, k->ed25519_pk, ED25519_PK_SZ)) != 0) goto out; break; default: ret = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 || (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 || (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0) goto out; if ((principals = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } for (i = 0; i < k->cert->nprincipals; i++) { if ((ret = sshbuf_put_cstring(principals, k->cert->principals[i])) != 0) goto out; } if ((ret = sshbuf_put_stringb(cert, principals)) != 0 || (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 || (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 || (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 || (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 || (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */ (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0) goto out; /* Sign the whole mess */ if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), sshbuf_len(cert), NULL, 0)) != 0) goto out; /* Append signature and we are done */ if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0) goto out; ret = 0; out: if (ret != 0) sshbuf_reset(cert); free(sig_blob); free(ca_blob); sshbuf_free(principals); return ret; } int sshkey_cert_check_authority(const struct sshkey *k, int want_host, int require_principal, const char *name, const char **reason) { u_int i, principal_matches; time_t now = time(NULL); if (reason != NULL) *reason = NULL; if (want_host) { if (k->cert->type != SSH2_CERT_TYPE_HOST) { *reason = "Certificate invalid: not a host certificate"; return SSH_ERR_KEY_CERT_INVALID; } } else { if (k->cert->type != SSH2_CERT_TYPE_USER) { *reason = "Certificate invalid: not a user certificate"; return SSH_ERR_KEY_CERT_INVALID; } } if (now < 0) { /* yikes - system clock before epoch! */ *reason = "Certificate invalid: not yet valid"; return SSH_ERR_KEY_CERT_INVALID; } if ((u_int64_t)now < k->cert->valid_after) { *reason = "Certificate invalid: not yet valid"; return SSH_ERR_KEY_CERT_INVALID; } if ((u_int64_t)now >= k->cert->valid_before) { *reason = "Certificate invalid: expired"; return SSH_ERR_KEY_CERT_INVALID; } if (k->cert->nprincipals == 0) { if (require_principal) { *reason = "Certificate lacks principal list"; return SSH_ERR_KEY_CERT_INVALID; } } else if (name != NULL) { principal_matches = 0; for (i = 0; i < k->cert->nprincipals; i++) { if (strcmp(name, k->cert->principals[i]) == 0) { principal_matches = 1; break; } } if (!principal_matches) { *reason = "Certificate invalid: name is not a listed " "principal"; return SSH_ERR_KEY_CERT_INVALID; } } return 0; } size_t sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l) { char from[32], to[32], ret[64]; time_t tt; struct tm *tm; *from = *to = '\0'; if (cert->valid_after == 0 && cert->valid_before == 0xffffffffffffffffULL) return strlcpy(s, "forever", l); if (cert->valid_after != 0) { /* XXX revisit INT_MAX in 2038 :) */ tt = cert->valid_after > INT_MAX ? INT_MAX : cert->valid_after; tm = localtime(&tt); strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); } if (cert->valid_before != 0xffffffffffffffffULL) { /* XXX revisit INT_MAX in 2038 :) */ tt = cert->valid_before > INT_MAX ? INT_MAX : cert->valid_before; tm = localtime(&tt); strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); } if (cert->valid_after == 0) snprintf(ret, sizeof(ret), "before %s", to); else if (cert->valid_before == 0xffffffffffffffffULL) snprintf(ret, sizeof(ret), "after %s", from); else snprintf(ret, sizeof(ret), "from %s to %s", from, to); return strlcpy(s, ret, l); } int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) { int r = SSH_ERR_INTERNAL_ERROR; if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) goto out; switch (key->type) { #ifdef WITH_OPENSSL case KEY_RSA: if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) goto out; break; case KEY_RSA_CERT: if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) goto out; break; case KEY_DSA: if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) goto out; break; case KEY_DSA_CERT: if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) goto out; break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if ((r = sshbuf_put_cstring(b, sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || (r = sshbuf_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa))) != 0) goto out; break; case KEY_ECDSA_CERT: if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || (r = sshbuf_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa))) != 0) goto out; break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519: if ((r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0 || (r = sshbuf_put_string(b, key->ed25519_sk, ED25519_SK_SZ)) != 0) goto out; break; case KEY_ED25519_CERT: if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || (r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0 || (r = sshbuf_put_string(b, key->ed25519_sk, ED25519_SK_SZ)) != 0) goto out; break; default: r = SSH_ERR_INVALID_ARGUMENT; goto out; } /* success */ r = 0; out: return r; } int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) { char *tname = NULL, *curve = NULL; struct sshkey *k = NULL; size_t pklen = 0, sklen = 0; int type, r = SSH_ERR_INTERNAL_ERROR; u_char *ed25519_pk = NULL, *ed25519_sk = NULL; #ifdef WITH_OPENSSL BIGNUM *exponent = NULL; #endif /* WITH_OPENSSL */ if (kp != NULL) *kp = NULL; if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0) goto out; type = sshkey_type_from_name(tname); switch (type) { #ifdef WITH_OPENSSL case KEY_DSA: if ((k = sshkey_new_private(type)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) goto out; break; case KEY_DSA_CERT: if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) goto out; break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if ((k = sshkey_new_private(type)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0) goto out; if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { r = SSH_ERR_EC_CURVE_MISMATCH; goto out; } k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 || (r = sshbuf_get_bignum2(buf, exponent))) goto out; if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), EC_KEY_get0_public_key(k->ecdsa))) != 0 || (r = sshkey_ec_validate_private(k->ecdsa)) != 0) goto out; break; case KEY_ECDSA_CERT: if ((exponent = BN_new()) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, exponent)) != 0) goto out; if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), EC_KEY_get0_public_key(k->ecdsa))) != 0 || (r = sshkey_ec_validate_private(k->ecdsa)) != 0) goto out; break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: if ((k = sshkey_new_private(type)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || (r = rsa_generate_additional_parameters(k->rsa)) != 0) goto out; break; case KEY_RSA_CERT: if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || (r = rsa_generate_additional_parameters(k->rsa)) != 0) goto out; break; #endif /* WITH_OPENSSL */ case KEY_ED25519: if ((k = sshkey_new_private(type)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) goto out; if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { r = SSH_ERR_INVALID_FORMAT; goto out; } k->ed25519_pk = ed25519_pk; k->ed25519_sk = ed25519_sk; ed25519_pk = ed25519_sk = NULL; break; case KEY_ED25519_CERT: if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) goto out; if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { r = SSH_ERR_INVALID_FORMAT; goto out; } k->ed25519_pk = ed25519_pk; k->ed25519_sk = ed25519_sk; ed25519_pk = ed25519_sk = NULL; break; default: r = SSH_ERR_KEY_TYPE_UNKNOWN; goto out; } #ifdef WITH_OPENSSL /* enable blinding */ switch (k->type) { case KEY_RSA: case KEY_RSA_CERT: case KEY_RSA1: if (RSA_blinding_on(k->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } break; } #endif /* WITH_OPENSSL */ /* success */ r = 0; if (kp != NULL) { *kp = k; k = NULL; } out: free(tname); free(curve); #ifdef WITH_OPENSSL if (exponent != NULL) BN_clear_free(exponent); #endif /* WITH_OPENSSL */ sshkey_free(k); if (ed25519_pk != NULL) { explicit_bzero(ed25519_pk, pklen); free(ed25519_pk); } if (ed25519_sk != NULL) { explicit_bzero(ed25519_sk, sklen); free(ed25519_sk); } return r; } #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) { BN_CTX *bnctx; EC_POINT *nq = NULL; BIGNUM *order, *x, *y, *tmp; int ret = SSH_ERR_KEY_INVALID_EC_VALUE; if ((bnctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; BN_CTX_start(bnctx); /* * We shouldn't ever hit this case because bignum_get_ecpoint() * refuses to load GF2m points. */ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_prime_field) goto out; /* Q != infinity */ if (EC_POINT_is_at_infinity(group, public)) goto out; if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL || (order = BN_CTX_get(bnctx)) == NULL || (tmp = BN_CTX_get(bnctx)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ if (EC_GROUP_get_order(group, order, bnctx) != 1 || EC_POINT_get_affine_coordinates_GFp(group, public, x, y, bnctx) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (BN_num_bits(x) <= BN_num_bits(order) / 2 || BN_num_bits(y) <= BN_num_bits(order) / 2) goto out; /* nQ == infinity (n == order of subgroup) */ if ((nq = EC_POINT_new(group)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (EC_POINT_is_at_infinity(group, nq) != 1) goto out; /* x < order - 1, y < order - 1 */ if (!BN_sub(tmp, order, BN_value_one())) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0) goto out; ret = 0; out: BN_CTX_free(bnctx); if (nq != NULL) EC_POINT_free(nq); return ret; } int sshkey_ec_validate_private(const EC_KEY *key) { BN_CTX *bnctx; BIGNUM *order, *tmp; int ret = SSH_ERR_KEY_INVALID_EC_VALUE; if ((bnctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; BN_CTX_start(bnctx); if ((order = BN_CTX_get(bnctx)) == NULL || (tmp = BN_CTX_get(bnctx)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } /* log2(private) > log2(order)/2 */ if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (BN_num_bits(EC_KEY_get0_private_key(key)) <= BN_num_bits(order) / 2) goto out; /* private < order - 1 */ if (!BN_sub(tmp, order, BN_value_one())) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) goto out; ret = 0; out: BN_CTX_free(bnctx); return ret; } void sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) { BIGNUM *x, *y; BN_CTX *bnctx; if (point == NULL) { fputs("point=(NULL)\n", stderr); return; } if ((bnctx = BN_CTX_new()) == NULL) { fprintf(stderr, "%s: BN_CTX_new failed\n", __func__); return; } BN_CTX_start(bnctx); if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) { fprintf(stderr, "%s: BN_CTX_get failed\n", __func__); return; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_prime_field) { fprintf(stderr, "%s: group is not a prime field\n", __func__); return; } if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) { fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", __func__); return; } fputs("x=", stderr); BN_print_fp(stderr, x); fputs("\ny=", stderr); BN_print_fp(stderr, y); fputs("\n", stderr); BN_CTX_free(bnctx); } void sshkey_dump_ec_key(const EC_KEY *key) { const BIGNUM *exponent; sshkey_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); fputs("exponent=", stderr); if ((exponent = EC_KEY_get0_private_key(key)) == NULL) fputs("(NULL)", stderr); else BN_print_fp(stderr, EC_KEY_get0_private_key(key)); fputs("\n", stderr); } #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ static int sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, const char *passphrase, const char *comment, const char *ciphername, int rounds) { u_char *cp, *key = NULL, *pubkeyblob = NULL; u_char salt[SALT_LEN]; char *b64 = NULL; size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; u_int check; int r = SSH_ERR_INTERNAL_ERROR; struct sshcipher_ctx ciphercontext; const struct sshcipher *cipher; const char *kdfname = KDFNAME; struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; memset(&ciphercontext, 0, sizeof(ciphercontext)); if (rounds <= 0) rounds = DEFAULT_ROUNDS; if (passphrase == NULL || !strlen(passphrase)) { ciphername = "none"; kdfname = "none"; } else if (ciphername == NULL) ciphername = DEFAULT_CIPHERNAME; else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_INTERNAL_ERROR; goto out; } if ((kdf = sshbuf_new()) == NULL || (encoded = sshbuf_new()) == NULL || (encrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } blocksize = cipher_blocksize(cipher); keylen = cipher_keylen(cipher); ivlen = cipher_ivlen(cipher); authlen = cipher_authlen(cipher); if ((key = calloc(1, keylen + ivlen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (strcmp(kdfname, "bcrypt") == 0) { arc4random_buf(salt, SALT_LEN); if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 || (r = sshbuf_put_u32(kdf, rounds)) != 0) goto out; } else if (strcmp(kdfname, "none") != 0) { /* Unsupported KDF type */ r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; } if ((r = cipher_init(&ciphercontext, cipher, key, keylen, key + keylen, ivlen, 1)) != 0) goto out; if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || (r = sshbuf_put_cstring(encoded, ciphername)) != 0 || (r = sshbuf_put_cstring(encoded, kdfname)) != 0 || (r = sshbuf_put_stringb(encoded, kdf)) != 0 || (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */ (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 || (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0) goto out; /* set up the buffer that will be encrypted */ /* Random check bytes */ check = arc4random(); if ((r = sshbuf_put_u32(encrypted, check)) != 0 || (r = sshbuf_put_u32(encrypted, check)) != 0) goto out; /* append private key and comment*/ if ((r = sshkey_private_serialize(prv, encrypted)) != 0 || (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; /* padding */ i = 0; while (sshbuf_len(encrypted) % blocksize) { if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0) goto out; } /* length in destination buffer */ if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0) goto out; /* encrypt */ if ((r = sshbuf_reserve(encoded, sshbuf_len(encrypted) + authlen, &cp)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, 0, cp, sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) goto out; /* uuencode */ if ((b64 = sshbuf_dtob64(encoded)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } sshbuf_reset(blob); if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0) goto out; for (i = 0; i < strlen(b64); i++) { if ((r = sshbuf_put_u8(blob, b64[i])) != 0) goto out; /* insert line breaks */ if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) goto out; } if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) goto out; if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0) goto out; /* success */ r = 0; out: sshbuf_free(kdf); sshbuf_free(encoded); sshbuf_free(encrypted); cipher_cleanup(&ciphercontext); explicit_bzero(salt, sizeof(salt)); if (key != NULL) { explicit_bzero(key, keylen + ivlen); free(key); } if (pubkeyblob != NULL) { explicit_bzero(pubkeyblob, pubkeylen); free(pubkeyblob); } if (b64 != NULL) { explicit_bzero(b64, strlen(b64)); free(b64); } return r; } static int sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { char *comment = NULL, *ciphername = NULL, *kdfname = NULL; const struct sshcipher *cipher = NULL; const u_char *cp; int r = SSH_ERR_INTERNAL_ERROR; size_t encoded_len; size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; struct sshbuf *encoded = NULL, *decoded = NULL; struct sshbuf *kdf = NULL, *decrypted = NULL; struct sshcipher_ctx ciphercontext; struct sshkey *k = NULL; u_char *key = NULL, *salt = NULL, *dp, pad, last; u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; memset(&ciphercontext, 0, sizeof(ciphercontext)); if (keyp != NULL) *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((encoded = sshbuf_new()) == NULL || (decoded = sshbuf_new()) == NULL || (decrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* check preamble */ cp = sshbuf_ptr(blob); encoded_len = sshbuf_len(blob); if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) || memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } cp += MARK_BEGIN_LEN; encoded_len -= MARK_BEGIN_LEN; /* Look for end marker, removing whitespace as we go */ while (encoded_len > 0) { if (*cp != '\n' && *cp != '\r') { if ((r = sshbuf_put_u8(encoded, *cp)) != 0) goto out; } last = *cp; encoded_len--; cp++; if (last == '\n') { if (encoded_len >= MARK_END_LEN && memcmp(cp, MARK_END, MARK_END_LEN) == 0) { /* \0 terminate */ if ((r = sshbuf_put_u8(encoded, 0)) != 0) goto out; break; } } } if (encoded_len == 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* decode base64 */ if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0) goto out; /* check magic */ if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) || memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* parse public portion of key */ if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 || (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 || (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 || (r = sshbuf_froms(decoded, &kdf)) != 0 || (r = sshbuf_get_u32(decoded, &nkeys)) != 0 || (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */ (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) goto out; if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; } if ((passphrase == NULL || strlen(passphrase) == 0) && strcmp(ciphername, "none") != 0) { /* passphrase required */ r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; } if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } if (nkeys != 1) { /* XXX only one key supported */ r = SSH_ERR_INVALID_FORMAT; goto out; } /* check size of encrypted key blob */ blocksize = cipher_blocksize(cipher); if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* setup key */ keylen = cipher_keylen(cipher); ivlen = cipher_ivlen(cipher); authlen = cipher_authlen(cipher); if ((key = calloc(1, keylen + ivlen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if (strcmp(kdfname, "bcrypt") == 0) { if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 || (r = sshbuf_get_u32(kdf, &rounds)) != 0) goto out; if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, key, keylen + ivlen, rounds) < 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } } /* check that an appropriate amount of auth data is present */ if (sshbuf_len(decoded) < encrypted_len + authlen) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* decrypt private portion of key */ if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || (r = cipher_init(&ciphercontext, cipher, key, keylen, key + keylen, ivlen, 0)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded), encrypted_len, 0, authlen)) != 0) { /* an integrity error here indicates an incorrect passphrase */ if (r == SSH_ERR_MAC_INVALID) r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0) goto out; /* there should be no trailing data */ if (sshbuf_len(decoded) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } /* check check bytes */ if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 || (r = sshbuf_get_u32(decrypted, &check2)) != 0) goto out; if (check1 != check2) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } /* Load the private key and comment */ if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 || (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0) goto out; /* Check deterministic padding */ i = 0; while (sshbuf_len(decrypted)) { if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) goto out; if (pad != (++i & 0xff)) { r = SSH_ERR_INVALID_FORMAT; goto out; } } /* XXX decode pubkey and check against private */ /* success */ r = 0; if (keyp != NULL) { *keyp = k; k = NULL; } if (commentp != NULL) { *commentp = comment; comment = NULL; } out: pad = 0; cipher_cleanup(&ciphercontext); free(ciphername); free(kdfname); free(comment); if (salt != NULL) { explicit_bzero(salt, slen); free(salt); } if (key != NULL) { explicit_bzero(key, keylen + ivlen); free(key); } sshbuf_free(encoded); sshbuf_free(decoded); sshbuf_free(kdf); sshbuf_free(decrypted); sshkey_free(k); return r; } #if WITH_SSH1 /* * Serialises the authentication (private) key to a blob, encrypting it with * passphrase. The identification of the blob (lowest 64 bits of n) will * precede the key to provide identification of the key without needing a * passphrase. */ static int sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, const char *passphrase, const char *comment) { struct sshbuf *buffer = NULL, *encrypted = NULL; u_char buf[8]; int r, cipher_num; struct sshcipher_ctx ciphercontext; const struct sshcipher *cipher; u_char *cp; /* * 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_CIPHER_3DES; if ((cipher = cipher_by_number(cipher_num)) == NULL) return SSH_ERR_INTERNAL_ERROR; /* This buffer is used to build the secret part of the private key. */ if ((buffer = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Put checkbytes for checking passphrase validity. */ if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0) goto out; arc4random_buf(cp, 2); memcpy(cp + 2, cp, 2); /* * 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). * Note: q and p are stored in reverse order to SSL. */ if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) goto out; /* Pad the part to be encrypted to a size that is a multiple of 8. */ explicit_bzero(buf, 8); if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0) goto out; /* This buffer will be used to contain the data in the file. */ if ((encrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } /* First store keyfile id string. */ if ((r = sshbuf_put(encrypted, LEGACY_BEGIN, sizeof(LEGACY_BEGIN))) != 0) goto out; /* Store cipher type and "reserved" field. */ if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 || (r = sshbuf_put_u32(encrypted, 0)) != 0) goto out; /* Store public key. This will be in plain text. */ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; /* Allocate space for the private part of the key in the buffer. */ if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0) goto out; if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_ENCRYPT)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, 0, cp, sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) goto out; if ((r = cipher_cleanup(&ciphercontext)) != 0) goto out; r = sshbuf_putb(blob, encrypted); out: explicit_bzero(&ciphercontext, sizeof(ciphercontext)); explicit_bzero(buf, sizeof(buf)); sshbuf_free(buffer); sshbuf_free(encrypted); return r; } #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL /* convert SSH v2 key in OpenSSL PEM format */ static int sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, const char *_passphrase, const char *comment) { int success, r; int blen, len = strlen(_passphrase); u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; #if (OPENSSL_VERSION_NUMBER < 0x00907000L) const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; #else const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; #endif const u_char *bptr; BIO *bio = NULL; if (len > 0 && len <= 4) return SSH_ERR_PASSPHRASE_TOO_SHORT; if ((bio = BIO_new(BIO_s_mem())) == NULL) return SSH_ERR_ALLOC_FAIL; switch (key->type) { case KEY_DSA: success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, cipher, passphrase, len, NULL, NULL); break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, cipher, passphrase, len, NULL, NULL); break; #endif case KEY_RSA: success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, cipher, passphrase, len, NULL, NULL); break; default: success = 0; break; } if (success == 0) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { r = SSH_ERR_INTERNAL_ERROR; goto out; } if ((r = sshbuf_put(blob, bptr, blen)) != 0) goto out; r = 0; out: BIO_free(bio); return r; } #endif /* WITH_OPENSSL */ /* Serialise "key" to buffer "blob" */ int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, const char *passphrase, const char *comment, int force_new_format, const char *new_format_cipher, int new_format_rounds) { switch (key->type) { #ifdef WITH_SSH1 case KEY_RSA1: return sshkey_private_rsa1_to_blob(key, blob, passphrase, comment); #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL case KEY_DSA: case KEY_ECDSA: case KEY_RSA: if (force_new_format) { return sshkey_private_to_blob2(key, blob, passphrase, comment, new_format_cipher, new_format_rounds); } return sshkey_private_pem_to_blob(key, blob, passphrase, comment); #endif /* WITH_OPENSSL */ case KEY_ED25519: return sshkey_private_to_blob2(key, blob, passphrase, comment, new_format_cipher, new_format_rounds); default: return SSH_ERR_KEY_TYPE_UNKNOWN; } } #ifdef WITH_SSH1 /* * Parse the public, unencrypted portion of a RSA1 key. */ int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, struct sshkey **keyp, char **commentp) { int r; struct sshkey *pub = NULL; struct sshbuf *copy = NULL; if (keyp != NULL) *keyp = NULL; if (commentp != NULL) *commentp = NULL; /* Check that it is at least big enough to contain the ID string. */ if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) return SSH_ERR_INVALID_FORMAT; /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) return SSH_ERR_INVALID_FORMAT; /* Make a working copy of the keyblob and skip past the magic */ if ((copy = sshbuf_fromb(blob)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) goto out; /* Skip cipher type, reserved data and key bits. */ if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */ (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */ (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */ goto out; /* Read the public key from the buffer. */ if ((pub = sshkey_new(KEY_RSA1)) == NULL || (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) goto out; /* Finally, the comment */ if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) goto out; /* The encrypted private part is not parsed by this function. */ r = 0; if (keyp != NULL) *keyp = pub; else sshkey_free(pub); pub = NULL; out: sshbuf_free(copy); sshkey_free(pub); return r; } static int sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, struct sshkey **keyp, char **commentp) { int r; u_int16_t check1, check2; u_int8_t cipher_type; struct sshbuf *decrypted = NULL, *copy = NULL; u_char *cp; char *comment = NULL; struct sshcipher_ctx ciphercontext; const struct sshcipher *cipher; struct sshkey *prv = NULL; *keyp = NULL; if (commentp != NULL) *commentp = NULL; /* Check that it is at least big enough to contain the ID string. */ if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) return SSH_ERR_INVALID_FORMAT; /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) return SSH_ERR_INVALID_FORMAT; if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((copy = sshbuf_fromb(blob)) == NULL || (decrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) goto out; /* Read cipher type. */ if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 || (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */ goto out; /* Read the public key and comment from the buffer. */ if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) goto out; /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; } /* Initialize space for decrypted data. */ if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0) goto out; /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, 0, cp, sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { cipher_cleanup(&ciphercontext); goto out; } if ((r = cipher_cleanup(&ciphercontext)) != 0) goto out; if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || (r = sshbuf_get_u16(decrypted, &check2)) != 0) goto out; if (check1 != check2) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } /* Read the rest of the private key. */ if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) goto out; /* calculate p-1 and q-1 */ if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) goto out; /* enable blinding */ if (RSA_blinding_on(prv->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; *keyp = prv; prv = NULL; if (commentp != NULL) { *commentp = comment; comment = NULL; } out: explicit_bzero(&ciphercontext, sizeof(ciphercontext)); free(comment); sshkey_free(prv); sshbuf_free(copy); sshbuf_free(decrypted); return r; } #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL static int sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp) { EVP_PKEY *pk = NULL; struct sshkey *prv = NULL; BIO *bio = NULL; int r; *keyp = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) return SSH_ERR_ALLOC_FAIL; if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != (int)sshbuf_len(blob)) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase)) == NULL) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; #ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8); #endif if (RSA_blinding_on(prv->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } } else if (pk->type == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif #ifdef OPENSSL_HAS_ECC } else if (pk->type == EVP_PKEY_EC && (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); prv->type = KEY_ECDSA; prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); if (prv->ecdsa_nid == -1 || sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), EC_KEY_get0_public_key(prv->ecdsa)) != 0 || sshkey_ec_validate_private(prv->ecdsa) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } # ifdef DEBUG_PK if (prv != NULL && prv->ecdsa != NULL) sshkey_dump_ec_key(prv->ecdsa); # endif #endif /* OPENSSL_HAS_ECC */ } else { r = SSH_ERR_INVALID_FORMAT; goto out; } r = 0; *keyp = prv; prv = NULL; out: BIO_free(bio); if (pk != NULL) EVP_PKEY_free(pk); sshkey_free(prv); return r; } #endif /* WITH_OPENSSL */ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { *keyp = NULL; if (commentp != NULL) *commentp = NULL; switch (type) { #ifdef WITH_SSH1 case KEY_RSA1: return sshkey_parse_private_rsa1(blob, passphrase, keyp, commentp); #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL case KEY_DSA: case KEY_ECDSA: case KEY_RSA: return sshkey_parse_private_pem_fileblob(blob, type, passphrase, keyp); #endif /* WITH_OPENSSL */ case KEY_ED25519: return sshkey_parse_private2(blob, type, passphrase, keyp, commentp); case KEY_UNSPEC: if (sshkey_parse_private2(blob, type, passphrase, keyp, commentp) == 0) return 0; #ifdef WITH_OPENSSL return sshkey_parse_private_pem_fileblob(blob, type, passphrase, keyp); #else return SSH_ERR_INVALID_FORMAT; #endif /* WITH_OPENSSL */ default: return SSH_ERR_KEY_TYPE_UNKNOWN; } } int sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, struct sshkey **keyp, char **commentp) { if (keyp != NULL) *keyp = NULL; if (commentp != NULL) *commentp = NULL; #ifdef WITH_SSH1 /* it's a SSH v1 key if the public key part is readable */ if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) { return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, passphrase, keyp, commentp); } #endif /* WITH_SSH1 */ return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, passphrase, keyp, commentp); } openssh-7.2p2/sshkey.h010064400017500001750000000201621267006270000131320ustar00djmdjm/* $OpenBSD: sshkey.h,v 1.12 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 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 SSHKEY_H #define SSHKEY_H #include #ifdef WITH_OPENSSL #include #include # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ # define EC_KEY void # define EC_GROUP void # define EC_POINT void # endif /* OPENSSL_HAS_ECC */ #else /* WITH_OPENSSL */ # define RSA void # define DSA void # define EC_KEY void # define EC_GROUP void # define EC_POINT void #endif /* WITH_OPENSSL */ #define SSH_RSA_MINIMUM_MODULUS_SIZE 768 #define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20) struct sshbuf; /* Key types */ enum sshkey_types { KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, KEY_RSA_CERT, KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, KEY_UNSPEC }; /* Default fingerprint hash */ #define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256 /* Fingerprint representation formats */ enum sshkey_fp_rep { SSH_FP_DEFAULT = 0, SSH_FP_HEX, SSH_FP_BASE64, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART }; /* key is stored in external hardware */ #define SSHKEY_FLAG_EXT 0x0001 #define SSHKEY_CERT_MAX_PRINCIPALS 256 /* XXX opaquify? */ struct sshkey_cert { struct sshbuf *certblob; /* Kept around for use on wire */ u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */ u_int64_t serial; char *key_id; u_int nprincipals; char **principals; u_int64_t valid_after, valid_before; struct sshbuf *critical; struct sshbuf *extensions; struct sshkey *signature_key; }; /* XXX opaquify? */ struct sshkey { int type; int flags; RSA *rsa; DSA *dsa; int ecdsa_nid; /* NID of curve */ EC_KEY *ecdsa; u_char *ed25519_sk; u_char *ed25519_pk; struct sshkey_cert *cert; }; #define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES #define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES struct sshkey *sshkey_new(int); int sshkey_add_private(struct sshkey *); struct sshkey *sshkey_new_private(int); void sshkey_free(struct sshkey *); int sshkey_demote(const struct sshkey *, struct sshkey **); int sshkey_equal_public(const struct sshkey *, const struct sshkey *); int sshkey_equal(const struct sshkey *, const struct sshkey *); char *sshkey_fingerprint(const struct sshkey *, int, enum sshkey_fp_rep); int sshkey_fingerprint_raw(const struct sshkey *k, int, u_char **retp, size_t *lenp); const char *sshkey_type(const struct sshkey *); const char *sshkey_cert_type(const struct sshkey *); int sshkey_write(const struct sshkey *, FILE *); int sshkey_read(struct sshkey *, char **); u_int sshkey_size(const struct sshkey *); int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); int sshkey_type_from_name(const char *); int sshkey_is_cert(const struct sshkey *); int sshkey_type_is_cert(int); int sshkey_type_plain(int); int sshkey_to_certified(struct sshkey *); int sshkey_drop_cert(struct sshkey *); int sshkey_certify(struct sshkey *, struct sshkey *); int sshkey_cert_copy(const struct sshkey *, struct sshkey *); int sshkey_cert_check_authority(const struct sshkey *, int, int, const char *, const char **); size_t sshkey_format_cert_validity(const struct sshkey_cert *, char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); int sshkey_ecdsa_nid_from_name(const char *); int sshkey_curve_name_to_nid(const char *); const char * sshkey_curve_nid_to_name(int); u_int sshkey_curve_nid_to_bits(int); int sshkey_ecdsa_bits_to_nid(int); int sshkey_ecdsa_key_to_nid(EC_KEY *); int sshkey_ec_nid_to_hash_alg(int nid); int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_private(const EC_KEY *); const char *sshkey_ssh_name(const struct sshkey *); const char *sshkey_ssh_name_plain(const struct sshkey *); int sshkey_names_valid2(const char *, int); char *key_alg_list(int, int); int sshkey_from_blob(const u_char *, size_t, struct sshkey **); int sshkey_fromb(struct sshbuf *, struct sshkey **); int sshkey_froms(struct sshbuf *, struct sshkey **); int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); int sshkey_to_base64(const struct sshkey *, char **); int sshkey_putb(const struct sshkey *, struct sshbuf *); int sshkey_puts(const struct sshkey *, struct sshbuf *); int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); int sshkey_sign(const struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); int sshkey_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); /* for debug */ void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); void sshkey_dump_ec_key(const EC_KEY *); /* private key parsing and serialisation */ int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf); int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); /* private key file format parsing and serialisation */ int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, const char *passphrase, const char *comment, int force_new_format, const char *new_format_cipher, int new_format_rounds); int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, struct sshkey **keyp, char **commentp); int sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, struct sshkey **keyp, char **commentp); int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp); #ifdef SSHKEY_INTERNAL int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *ident); int ssh_rsa_verify(const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t datalen); int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat); int ssh_dss_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat); int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat); int ssh_ecdsa_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat); int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat); int ssh_ed25519_verify(const struct sshkey *key, const u_char *signature, size_t signaturelen, const u_char *data, size_t datalen, u_int compat); #endif #if !defined(WITH_OPENSSL) # undef RSA # undef DSA # undef EC_KEY # undef EC_GROUP # undef EC_POINT #elif !defined(OPENSSL_HAS_ECC) # undef EC_KEY # undef EC_GROUP # undef EC_POINT #endif #endif /* SSHKEY_H */ openssh-7.2p2/sshlogin.c010064400017500001750000000121631267006270000134470ustar00djmdjm/* $OpenBSD: sshlogin.c,v 1.32 2015/12/26 20:51:35 guenther Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * This file performs some of the things login(1) normally does. We cannot * easily use something like login -p -h host -f user, because there are * several different logins around, and it is hard to determined what kind of * login the current system has. Also, we want to be able to execute commands * on a tty. * * 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 Theo de Raadt. All rights reserved. * Copyright (c) 1999 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 #include #include #include #include #include #include #include #include #include #include #include "loginrec.h" #include "log.h" #include "buffer.h" #include "misc.h" #include "servconf.h" extern Buffer loginmsg; extern ServerOptions options; /* * Returns the time when the user last logged in. Returns 0 if the * information is not available. This must be called before record_login. * The host the user logged in from will be returned in buf. */ time_t get_last_login_time(uid_t uid, const char *logname, char *buf, size_t bufsize) { struct logininfo li; login_get_lastlog(&li, uid); strlcpy(buf, li.hostname, bufsize); return (time_t)li.tv_sec; } /* * Generate and store last login message. This must be done before * login_login() is called and lastlog is updated. */ static void store_lastlog_message(const char *user, uid_t uid) { #ifndef NO_SSH_LASTLOG char *time_string, hostname[HOST_NAME_MAX+1] = "", buf[512]; time_t last_login_time; if (!options.print_lastlog) return; # ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG time_string = sys_auth_get_lastlogin_msg(user, uid); if (time_string != NULL) { buffer_append(&loginmsg, time_string, strlen(time_string)); free(time_string); } # else last_login_time = get_last_login_time(uid, user, hostname, sizeof(hostname)); if (last_login_time != 0) { time_string = ctime(&last_login_time); time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) snprintf(buf, sizeof(buf), "Last login: %s\r\n", time_string); else snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", time_string, hostname); buffer_append(&loginmsg, buf, strlen(buf)); } # endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */ #endif /* NO_SSH_LASTLOG */ } /* * Records that the user has logged in. I wish these parts of operating * systems were more standardized. */ void record_login(pid_t pid, const char *tty, const char *user, uid_t uid, const char *host, struct sockaddr *addr, socklen_t addrlen) { struct logininfo *li; /* save previous login details before writing new */ store_lastlog_message(user, uid); li = login_alloc_entry(pid, user, host, tty); login_set_addr(li, addr, addrlen); login_login(li); login_free_entry(li); } #ifdef LOGIN_NEEDS_UTMPX void record_utmp_only(pid_t pid, const char *ttyname, const char *user, const char *host, struct sockaddr *addr, socklen_t addrlen) { struct logininfo *li; li = login_alloc_entry(pid, user, host, ttyname); login_set_addr(li, addr, addrlen); login_utmp_only(li); login_free_entry(li); } #endif /* Records that the user has logged out. */ void record_logout(pid_t pid, const char *tty, const char *user) { struct logininfo *li; li = login_alloc_entry(pid, user, NULL, tty); login_logout(li); login_free_entry(li); } openssh-7.2p2/sshlogin.h010064400017500001750000000016471267006270000134610ustar00djmdjm/* $OpenBSD: sshlogin.h,v 1.8 2006/08/03 03:34:42 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ void record_login(pid_t, const char *, const char *, uid_t, const char *, struct sockaddr *, socklen_t); void record_logout(pid_t, const char *, const char *); time_t get_last_login_time(uid_t, const char *, char *, size_t); #ifdef LOGIN_NEEDS_UTMPX void record_utmp_only(pid_t, const char *, const char *, const char *, struct sockaddr *, socklen_t); #endif openssh-7.2p2/sshpty.c010064400017500001750000000136451267006270000131610ustar00djmdjm/* $OpenBSD: sshpty.c,v 1.30 2015/07/30 23:09:15 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Allocating a pseudo-terminal, and making it the controlling tty. * * 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 #include #include #include #include #include #include #ifdef HAVE_PATHS_H # include #endif #include #include #include #include #ifdef HAVE_UTIL_H # include #endif #include #include "sshpty.h" #include "log.h" #include "misc.h" #ifdef HAVE_PTY_H # include #endif #ifndef O_NOCTTY #define O_NOCTTY 0 #endif #ifdef __APPLE__ # include # if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) # define __APPLE_PRIVPTY__ # endif #endif /* * Allocates and opens a pty. Returns 0 if no pty could be allocated, or * nonzero if a pty was successfully allocated. On success, open file * descriptors for the pty and tty sides and the name of the tty side are * returned (the buffer must be able to hold at least 64 characters). */ int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) { /* openpty(3) exists in OSF/1 and some other os'es */ char *name; int i; i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); if (i < 0) { error("openpty: %.100s", strerror(errno)); return 0; } name = ttyname(*ttyfd); if (!name) fatal("openpty returns device for which ttyname fails."); strlcpy(namebuf, name, namebuflen); /* possible truncation */ return 1; } /* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ void pty_release(const char *tty) { #if !defined(__APPLE_PRIVPTY__) && !defined(HAVE_OPENPTY) if (chown(tty, (uid_t) 0, (gid_t) 0) < 0) error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno)); if (chmod(tty, (mode_t) 0666) < 0) error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno)); #endif /* !__APPLE_PRIVPTY__ && !HAVE_OPENPTY */ } /* Makes the tty the process's controlling tty and sets it to sane modes. */ void pty_make_controlling_tty(int *ttyfd, const char *tty) { int fd; #ifdef _UNICOS if (setsid() < 0) error("setsid: %.100s", strerror(errno)); fd = open(tty, O_RDWR|O_NOCTTY); if (fd != -1) { signal(SIGHUP, SIG_IGN); ioctl(fd, TCVHUP, (char *)NULL); signal(SIGHUP, SIG_DFL); setpgid(0, 0); close(fd); } else { error("Failed to disconnect from controlling tty."); } debug("Setting controlling tty using TCSETCTTY."); ioctl(*ttyfd, TCSETCTTY, NULL); fd = open("/dev/tty", O_RDWR); if (fd < 0) error("%.100s: %.100s", tty, strerror(errno)); close(*ttyfd); *ttyfd = fd; #else /* _UNICOS */ /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ if (setsid() < 0) error("setsid: %.100s", strerror(errno)); /* * Verify that we are successfully disconnected from the controlling * tty. */ fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { error("Failed to disconnect from controlling tty."); close(fd); } /* Make it our controlling tty. */ #ifdef TIOCSCTTY debug("Setting controlling tty using TIOCSCTTY."); if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); #endif /* TIOCSCTTY */ #ifdef NEED_SETPGRP if (setpgrp(0,0) < 0) error("SETPGRP %s",strerror(errno)); #endif /* NEED_SETPGRP */ fd = open(tty, O_RDWR); if (fd < 0) { error("%.100s: %.100s", tty, strerror(errno)); } else { close(fd); } /* Verify that we now have a controlling tty. */ fd = open(_PATH_TTY, O_WRONLY); if (fd < 0) error("open /dev/tty failed - could not set controlling tty: %.100s", strerror(errno)); else close(fd); #endif /* _UNICOS */ } /* Changes the window size associated with the pty. */ void pty_change_window_size(int ptyfd, u_int row, u_int col, u_int xpixel, u_int ypixel) { struct winsize w; /* may truncate u_int -> u_short */ w.ws_row = row; w.ws_col = col; w.ws_xpixel = xpixel; w.ws_ypixel = ypixel; (void) ioctl(ptyfd, TIOCSWINSZ, &w); } void pty_setowner(struct passwd *pw, const char *tty) { struct group *grp; gid_t gid; mode_t mode; struct stat st; /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; mode = (grp != NULL) ? 0620 : 0600; /* * Change owner and mode of the tty as required. * Warn but continue if filesystem is read-only and the uids match/ * tty is owned by root. */ if (stat(tty, &st)) fatal("stat(%.100s) failed: %.100s", tty, strerror(errno)); #ifdef WITH_SELINUX ssh_selinux_setup_pty(pw->pw_name, tty); #endif if (st.st_uid != pw->pw_uid || st.st_gid != gid) { if (chown(tty, pw->pw_uid, gid) < 0) { if (errno == EROFS && (st.st_uid == pw->pw_uid || st.st_uid == 0)) debug("chown(%.100s, %u, %u) failed: %.100s", tty, (u_int)pw->pw_uid, (u_int)gid, strerror(errno)); else fatal("chown(%.100s, %u, %u) failed: %.100s", tty, (u_int)pw->pw_uid, (u_int)gid, strerror(errno)); } } if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { if (chmod(tty, mode) < 0) { if (errno == EROFS && (st.st_mode & (S_IRGRP | S_IROTH)) == 0) debug("chmod(%.100s, 0%o) failed: %.100s", tty, (u_int)mode, strerror(errno)); else fatal("chmod(%.100s, 0%o) failed: %.100s", tty, (u_int)mode, strerror(errno)); } } } openssh-7.2p2/sshpty.h010064400017500001750000000017611267006270000131620ustar00djmdjm/* $OpenBSD: sshpty.h,v 1.12 2010/01/09 05:04:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for allocating a pseudo-terminal and making it the controlling * tty. * * 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 struct termios *get_saved_tio(void); void leave_raw_mode(int); void enter_raw_mode(int); int pty_allocate(int *, int *, char *, size_t); void pty_release(const char *); void pty_make_controlling_tty(int *, const char *); void pty_change_window_size(int, u_int, u_int, u_int, u_int); void pty_setowner(struct passwd *, const char *); openssh-7.2p2/sshtty.c010064400017500001750000000057131267006270000131620ustar00djmdjm/* $OpenBSD: sshtty.c,v 1.14 2010/01/09 05:04:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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. * Copyright (c) 2001 Kevin Steves. 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 #include #include #include #include "sshpty.h" static struct termios _saved_tio; static int _in_raw_mode = 0; struct termios * get_saved_tio(void) { return _in_raw_mode ? &_saved_tio : NULL; } void leave_raw_mode(int quiet) { if (!_in_raw_mode) return; if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) { if (!quiet) perror("tcsetattr"); } else _in_raw_mode = 0; } void enter_raw_mode(int quiet) { struct termios tio; if (tcgetattr(fileno(stdin), &tio) == -1) { if (!quiet) perror("tcgetattr"); return; } _saved_tio = tio; tio.c_iflag |= IGNPAR; tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); #ifdef IUCLC tio.c_iflag &= ~IUCLC; #endif tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); #ifdef IEXTEN tio.c_lflag &= ~IEXTEN; #endif tio.c_oflag &= ~OPOST; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) { if (!quiet) perror("tcsetattr"); } else _in_raw_mode = 1; } openssh-7.2p2/survey.sh.in010064400017500001750000000032711267006270000137530ustar00djmdjm#!/bin/sh # # Copyright (c) 2004, 2005 Darren Tucker # # 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. host="@host@" AWK="@AWK@" CC="@CC@" CPP="@CPP@" CFLAGS="@CFLAGS@" CPPFLAGS="@CPPFLAGS@" LDFLAGS="@LDFLAGS@" LIBS="@LIBS@" # Note format: # identifier: [data] CRCR echo "openssh-survey-version: 1" echo echo "openssh-version: `./ssh -V 2>&1`" echo configinv=`$AWK '/^ \\\$.*configure/' config.log | sed 's/^ \\\$ //g'` echo "configure-invocation: $configinv" echo echo "host: $host" echo echo "uname: `uname`" echo echo "uname-r: `uname -r`" echo echo "uname-m: `uname -m`" echo echo "uname-p: `uname -p`" echo echo "oslevel: `oslevel 2>/dev/null`" echo echo "oslevel-r: `oslevel -r 2>/dev/null`" echo echo "cc: $CC" echo echo "cflags: $CFLAGS" echo echo "cppflags: $CPPFLAGS" echo echo "ldflags: $LDFLAGS" echo echo "libs: $LIBS" echo echo "ccver-v: `$CC -v 2>&1 | sed '/^[ \t]*$/d'`" echo echo "ccver-V: `$CC -V 2>&1 | sed '/^[ \t]*$/d'`" echo echo "cppdefines:" ${CPP} -dM - * Copyright (c) 1995 Tatu Ylonen , 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". */ /* * SSH2 tty modes support by Kevin Steves. * Copyright (c) 2001 Kevin Steves. 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. */ /* * Encoding and decoding of terminal modes in a portable way. * Much of the format is defined in ttymodes.h; it is included multiple times * into this file with the appropriate macro definitions to generate the * suitable code. */ #include "includes.h" #include #include #include #include #include #include "packet.h" #include "log.h" #include "ssh1.h" #include "compat.h" #include "buffer.h" #define TTY_OP_END 0 /* * uint32 (u_int) follows speed in SSH1 and SSH2 */ #define TTY_OP_ISPEED_PROTO1 192 #define TTY_OP_OSPEED_PROTO1 193 #define TTY_OP_ISPEED_PROTO2 128 #define TTY_OP_OSPEED_PROTO2 129 /* * Converts POSIX speed_t to a baud rate. The values of the * constants for speed_t are not themselves portable. */ static int speed_to_baud(speed_t speed) { switch (speed) { case B0: return 0; case B50: return 50; case B75: return 75; case B110: return 110; case B134: return 134; case B150: return 150; case B200: return 200; case B300: return 300; case B600: return 600; case B1200: return 1200; case B1800: return 1800; case B2400: return 2400; case B4800: return 4800; case B9600: return 9600; #ifdef B19200 case B19200: return 19200; #else /* B19200 */ #ifdef EXTA case EXTA: return 19200; #endif /* EXTA */ #endif /* B19200 */ #ifdef B38400 case B38400: return 38400; #else /* B38400 */ #ifdef EXTB case EXTB: return 38400; #endif /* EXTB */ #endif /* B38400 */ #ifdef B7200 case B7200: return 7200; #endif /* B7200 */ #ifdef B14400 case B14400: return 14400; #endif /* B14400 */ #ifdef B28800 case B28800: return 28800; #endif /* B28800 */ #ifdef B57600 case B57600: return 57600; #endif /* B57600 */ #ifdef B76800 case B76800: return 76800; #endif /* B76800 */ #ifdef B115200 case B115200: return 115200; #endif /* B115200 */ #ifdef B230400 case B230400: return 230400; #endif /* B230400 */ default: return 9600; } } /* * Converts a numeric baud rate to a POSIX speed_t. */ static speed_t baud_to_speed(int baud) { switch (baud) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; #ifdef B19200 case 19200: return B19200; #else /* B19200 */ #ifdef EXTA case 19200: return EXTA; #endif /* EXTA */ #endif /* B19200 */ #ifdef B38400 case 38400: return B38400; #else /* B38400 */ #ifdef EXTB case 38400: return EXTB; #endif /* EXTB */ #endif /* B38400 */ #ifdef B7200 case 7200: return B7200; #endif /* B7200 */ #ifdef B14400 case 14400: return B14400; #endif /* B14400 */ #ifdef B28800 case 28800: return B28800; #endif /* B28800 */ #ifdef B57600 case 57600: return B57600; #endif /* B57600 */ #ifdef B76800 case 76800: return B76800; #endif /* B76800 */ #ifdef B115200 case 115200: return B115200; #endif /* B115200 */ #ifdef B230400 case 230400: return B230400; #endif /* B230400 */ default: return B9600; } } /* * Encode a special character into SSH line format. */ static u_int special_char_encode(cc_t c) { #ifdef _POSIX_VDISABLE if (c == _POSIX_VDISABLE) return 255; #endif /* _POSIX_VDISABLE */ return c; } /* * Decode a special character from SSH line format. */ static cc_t special_char_decode(u_int c) { #ifdef _POSIX_VDISABLE if (c == 255) return _POSIX_VDISABLE; #endif /* _POSIX_VDISABLE */ return c; } /* * Encodes terminal modes for the terminal referenced by fd * or tiop in a portable manner, and appends the modes to a packet * being constructed. */ void tty_make_modes(int fd, struct termios *tiop) { struct termios tio; int baud; Buffer buf; int tty_op_ospeed, tty_op_ispeed; void (*put_arg)(Buffer *, u_int); buffer_init(&buf); if (compat20) { tty_op_ospeed = TTY_OP_OSPEED_PROTO2; tty_op_ispeed = TTY_OP_ISPEED_PROTO2; put_arg = buffer_put_int; } else { tty_op_ospeed = TTY_OP_OSPEED_PROTO1; tty_op_ispeed = TTY_OP_ISPEED_PROTO1; put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; } if (tiop == NULL) { if (fd == -1) { debug("tty_make_modes: no fd or tio"); goto end; } if (tcgetattr(fd, &tio) == -1) { logit("tcgetattr: %.100s", strerror(errno)); goto end; } } else tio = *tiop; /* Store input and output baud rates. */ baud = speed_to_baud(cfgetospeed(&tio)); buffer_put_char(&buf, tty_op_ospeed); buffer_put_int(&buf, baud); baud = speed_to_baud(cfgetispeed(&tio)); buffer_put_char(&buf, tty_op_ispeed); buffer_put_int(&buf, baud); /* Store values of mode flags. */ #define TTYCHAR(NAME, OP) \ buffer_put_char(&buf, OP); \ put_arg(&buf, special_char_encode(tio.c_cc[NAME])); #define TTYMODE(NAME, FIELD, OP) \ buffer_put_char(&buf, OP); \ put_arg(&buf, ((tio.FIELD & NAME) != 0)); #include "ttymodes.h" #undef TTYCHAR #undef TTYMODE end: /* Mark end of mode data. */ buffer_put_char(&buf, TTY_OP_END); if (compat20) packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); else packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); buffer_free(&buf); } /* * Decodes terminal modes for the terminal referenced by fd in a portable * manner from a packet being read. */ void tty_parse_modes(int fd, int *n_bytes_ptr) { struct termios tio; int opcode, baud; int n_bytes = 0; int failure = 0; u_int (*get_arg)(void); int arg_size; if (compat20) { *n_bytes_ptr = packet_get_int(); if (*n_bytes_ptr == 0) return; get_arg = packet_get_int; arg_size = 4; } else { get_arg = packet_get_char; arg_size = 1; } /* * Get old attributes for the terminal. We will modify these * flags. I am hoping that if there are any machine-specific * modes, they will initially have reasonable values. */ if (tcgetattr(fd, &tio) == -1) { logit("tcgetattr: %.100s", strerror(errno)); failure = -1; } for (;;) { n_bytes += 1; opcode = packet_get_char(); switch (opcode) { case TTY_OP_END: goto set; /* XXX: future conflict possible */ case TTY_OP_ISPEED_PROTO1: case TTY_OP_ISPEED_PROTO2: n_bytes += 4; baud = packet_get_int(); if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) error("cfsetispeed failed for %d", baud); break; /* XXX: future conflict possible */ case TTY_OP_OSPEED_PROTO1: case TTY_OP_OSPEED_PROTO2: n_bytes += 4; baud = packet_get_int(); if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) error("cfsetospeed failed for %d", baud); break; #define TTYCHAR(NAME, OP) \ case OP: \ n_bytes += arg_size; \ tio.c_cc[NAME] = special_char_decode(get_arg()); \ break; #define TTYMODE(NAME, FIELD, OP) \ case OP: \ n_bytes += arg_size; \ if (get_arg()) \ tio.FIELD |= NAME; \ else \ tio.FIELD &= ~NAME; \ break; #include "ttymodes.h" #undef TTYCHAR #undef TTYMODE default: debug("Ignoring unsupported tty mode opcode %d (0x%x)", opcode, opcode); if (!compat20) { /* * SSH1: * Opcodes 1 to 127 are defined to have * a one-byte argument. * Opcodes 128 to 159 are defined to have * an integer argument. */ if (opcode > 0 && opcode < 128) { n_bytes += 1; (void) packet_get_char(); break; } else if (opcode >= 128 && opcode < 160) { n_bytes += 4; (void) packet_get_int(); break; } else { /* * It is a truly undefined opcode (160 to 255). * We have no idea about its arguments. So we * must stop parsing. Note that some data * may be left in the packet; hopefully there * is nothing more coming after the mode data. */ logit("parse_tty_modes: unknown opcode %d", opcode); goto set; } } else { /* * SSH2: * Opcodes 1 to 159 are defined to have * a uint32 argument. * Opcodes 160 to 255 are undefined and * cause parsing to stop. */ if (opcode > 0 && opcode < 160) { n_bytes += 4; (void) packet_get_int(); break; } else { logit("parse_tty_modes: unknown opcode %d", opcode); goto set; } } } } set: if (*n_bytes_ptr != n_bytes) { *n_bytes_ptr = n_bytes; logit("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", *n_bytes_ptr, n_bytes); return; /* Don't process bytes passed */ } if (failure == -1) return; /* Packet parsed ok but tcgetattr() failed */ /* Set the new modes for the terminal. */ if (tcsetattr(fd, TCSANOW, &tio) == -1) logit("Setting tty modes failed: %.100s", strerror(errno)); } openssh-7.2p2/ttymodes.h010064400017500001750000000123471267006270000135020ustar00djmdjm/* $OpenBSD: ttymodes.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ /* * SSH2 tty modes support by Kevin Steves. * Copyright (c) 2001 Kevin Steves. 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. */ /* * SSH1: * The tty mode description is a stream of bytes. The stream consists of * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer * arguments. Opcodes 160-255 are not yet defined, and cause parsing to * stop (they should only be used after any other data). * * SSH2: * Differences between SSH1 and SSH2 terminal mode encoding include: * 1. Encoded terminal modes are represented as a string, and a stream * of bytes within that string. * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined. * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different; * 128 and 129 vs. 192 and 193 respectively. * * The client puts in the stream any modes it knows about, and the * server ignores any modes it does not know about. This allows some degree * of machine-independence, at least between systems that use a posix-like * tty interface. The protocol can support other systems as well, but might * require reimplementing as mode names would likely be different. */ /* * Some constants and prototypes are defined in packet.h; this file * is only intended for including from ttymodes.c. */ /* termios macro */ /* name, op */ TTYCHAR(VINTR, 1) TTYCHAR(VQUIT, 2) TTYCHAR(VERASE, 3) #if defined(VKILL) TTYCHAR(VKILL, 4) #endif /* VKILL */ TTYCHAR(VEOF, 5) #if defined(VEOL) TTYCHAR(VEOL, 6) #endif /* VEOL */ #ifdef VEOL2 TTYCHAR(VEOL2, 7) #endif /* VEOL2 */ TTYCHAR(VSTART, 8) TTYCHAR(VSTOP, 9) #if defined(VSUSP) TTYCHAR(VSUSP, 10) #endif /* VSUSP */ #if defined(VDSUSP) TTYCHAR(VDSUSP, 11) #endif /* VDSUSP */ #if defined(VREPRINT) TTYCHAR(VREPRINT, 12) #endif /* VREPRINT */ #if defined(VWERASE) TTYCHAR(VWERASE, 13) #endif /* VWERASE */ #if defined(VLNEXT) TTYCHAR(VLNEXT, 14) #endif /* VLNEXT */ #if defined(VFLUSH) TTYCHAR(VFLUSH, 15) #endif /* VFLUSH */ #ifdef VSWTCH TTYCHAR(VSWTCH, 16) #endif /* VSWTCH */ #if defined(VSTATUS) TTYCHAR(VSTATUS, 17) #endif /* VSTATUS */ #ifdef VDISCARD TTYCHAR(VDISCARD, 18) #endif /* VDISCARD */ /* name, field, op */ TTYMODE(IGNPAR, c_iflag, 30) TTYMODE(PARMRK, c_iflag, 31) TTYMODE(INPCK, c_iflag, 32) TTYMODE(ISTRIP, c_iflag, 33) TTYMODE(INLCR, c_iflag, 34) TTYMODE(IGNCR, c_iflag, 35) TTYMODE(ICRNL, c_iflag, 36) #if defined(IUCLC) TTYMODE(IUCLC, c_iflag, 37) #endif TTYMODE(IXON, c_iflag, 38) TTYMODE(IXANY, c_iflag, 39) TTYMODE(IXOFF, c_iflag, 40) #ifdef IMAXBEL TTYMODE(IMAXBEL,c_iflag, 41) #endif /* IMAXBEL */ TTYMODE(ISIG, c_lflag, 50) TTYMODE(ICANON, c_lflag, 51) #ifdef XCASE TTYMODE(XCASE, c_lflag, 52) #endif TTYMODE(ECHO, c_lflag, 53) TTYMODE(ECHOE, c_lflag, 54) TTYMODE(ECHOK, c_lflag, 55) TTYMODE(ECHONL, c_lflag, 56) TTYMODE(NOFLSH, c_lflag, 57) TTYMODE(TOSTOP, c_lflag, 58) #ifdef IEXTEN TTYMODE(IEXTEN, c_lflag, 59) #endif /* IEXTEN */ #if defined(ECHOCTL) TTYMODE(ECHOCTL,c_lflag, 60) #endif /* ECHOCTL */ #ifdef ECHOKE TTYMODE(ECHOKE, c_lflag, 61) #endif /* ECHOKE */ #if defined(PENDIN) TTYMODE(PENDIN, c_lflag, 62) #endif /* PENDIN */ TTYMODE(OPOST, c_oflag, 70) #if defined(OLCUC) TTYMODE(OLCUC, c_oflag, 71) #endif #ifdef ONLCR TTYMODE(ONLCR, c_oflag, 72) #endif #ifdef OCRNL TTYMODE(OCRNL, c_oflag, 73) #endif #ifdef ONOCR TTYMODE(ONOCR, c_oflag, 74) #endif #ifdef ONLRET TTYMODE(ONLRET, c_oflag, 75) #endif TTYMODE(CS7, c_cflag, 90) TTYMODE(CS8, c_cflag, 91) TTYMODE(PARENB, c_cflag, 92) TTYMODE(PARODD, c_cflag, 93) openssh-7.2p2/uidswap.c010064400017500001750000000175511267006270000133030ustar00djmdjm/* $OpenBSD: uidswap.c,v 1.39 2015/06/24 01:49:19 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Code for uid-swapping. * * 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 #include #include #include #include #include #include #include #include "log.h" #include "uidswap.h" #include "xmalloc.h" /* * Note: all these functions must work in all of the following cases: * 1. euid=0, ruid=0 * 2. euid=0, ruid!=0 * 3. euid!=0, ruid!=0 * Additionally, they must work regardless of whether the system has * POSIX saved uids or not. */ #if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) /* Lets assume that posix saved ids also work with seteuid, even though that is not part of the posix specification. */ #define SAVED_IDS_WORK_WITH_SETEUID /* Saved effective uid. */ static uid_t saved_euid = 0; static gid_t saved_egid = 0; #endif /* Saved effective uid. */ static int privileged = 0; static int temporarily_use_uid_effective = 0; static gid_t *saved_egroups = NULL, *user_groups = NULL; static int saved_egroupslen = -1, user_groupslen = -1; /* * Temporarily changes to the given uid. If the effective user * id is not root, this does nothing. This call cannot be nested. */ void temporarily_use_uid(struct passwd *pw) { /* Save the current euid, and egroups. */ #ifdef SAVED_IDS_WORK_WITH_SETEUID saved_euid = geteuid(); saved_egid = getegid(); debug("temporarily_use_uid: %u/%u (e=%u/%u)", (u_int)pw->pw_uid, (u_int)pw->pw_gid, (u_int)saved_euid, (u_int)saved_egid); #ifndef HAVE_CYGWIN if (saved_euid != 0) { privileged = 0; return; } #endif #else if (geteuid() != 0) { privileged = 0; return; } #endif /* SAVED_IDS_WORK_WITH_SETEUID */ privileged = 1; temporarily_use_uid_effective = 1; saved_egroupslen = getgroups(0, NULL); if (saved_egroupslen < 0) fatal("getgroups: %.100s", strerror(errno)); if (saved_egroupslen > 0) { saved_egroups = xreallocarray(saved_egroups, saved_egroupslen, sizeof(gid_t)); if (getgroups(saved_egroupslen, saved_egroups) < 0) fatal("getgroups: %.100s", strerror(errno)); } else { /* saved_egroupslen == 0 */ free(saved_egroups); } /* set and save the user's groups */ if (user_groupslen == -1) { if (initgroups(pw->pw_name, pw->pw_gid) < 0) fatal("initgroups: %s: %.100s", pw->pw_name, strerror(errno)); user_groupslen = getgroups(0, NULL); if (user_groupslen < 0) fatal("getgroups: %.100s", strerror(errno)); if (user_groupslen > 0) { user_groups = xreallocarray(user_groups, user_groupslen, sizeof(gid_t)); if (getgroups(user_groupslen, user_groups) < 0) fatal("getgroups: %.100s", strerror(errno)); } else { /* user_groupslen == 0 */ free(user_groups); } } /* Set the effective uid to the given (unprivileged) uid. */ if (setgroups(user_groupslen, user_groups) < 0) fatal("setgroups: %.100s", strerror(errno)); #ifndef SAVED_IDS_WORK_WITH_SETEUID /* Propagate the privileged gid to all of our gids. */ if (setgid(getegid()) < 0) debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno)); /* Propagate the privileged uid to all of our uids. */ if (setuid(geteuid()) < 0) debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno)); #endif /* SAVED_IDS_WORK_WITH_SETEUID */ if (setegid(pw->pw_gid) < 0) fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); if (seteuid(pw->pw_uid) == -1) fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); } void permanently_drop_suid(uid_t uid) { #ifndef NO_UID_RESTORATION_TEST uid_t old_uid = getuid(); #endif debug("permanently_drop_suid: %u", (u_int)uid); if (setresuid(uid, uid, uid) < 0) fatal("setresuid %u: %.100s", (u_int)uid, strerror(errno)); #ifndef NO_UID_RESTORATION_TEST /* * Try restoration of UID if changed (test clearing of saved uid). * * Note that we don't do this on Cygwin, or on Solaris-based platforms * where fine-grained privileges are available (the user might be * deliberately allowed the right to setuid back to root). */ if (old_uid != uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) fatal("%s: was able to restore old [e]uid", __func__); #endif /* Verify UID drop was successful */ if (getuid() != uid || geteuid() != uid) { fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", __func__, (u_int)getuid(), (u_int)geteuid(), (u_int)uid); } } /* * Restores to the original (privileged) uid. */ void restore_uid(void) { /* it's a no-op unless privileged */ if (!privileged) { debug("restore_uid: (unprivileged)"); return; } if (!temporarily_use_uid_effective) fatal("restore_uid: temporarily_use_uid not effective"); #ifdef SAVED_IDS_WORK_WITH_SETEUID debug("restore_uid: %u/%u", (u_int)saved_euid, (u_int)saved_egid); /* Set the effective uid back to the saved privileged uid. */ if (seteuid(saved_euid) < 0) fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno)); if (setegid(saved_egid) < 0) fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno)); #else /* SAVED_IDS_WORK_WITH_SETEUID */ /* * We are unable to restore the real uid to its unprivileged value. * Propagate the real uid (usually more privileged) to effective uid * as well. */ setuid(getuid()); setgid(getgid()); #endif /* SAVED_IDS_WORK_WITH_SETEUID */ if (setgroups(saved_egroupslen, saved_egroups) < 0) fatal("setgroups: %.100s", strerror(errno)); temporarily_use_uid_effective = 0; } /* * Permanently sets all uids to the given uid. This cannot be * called while temporarily_use_uid is effective. */ void permanently_set_uid(struct passwd *pw) { #ifndef NO_UID_RESTORATION_TEST uid_t old_uid = getuid(); gid_t old_gid = getgid(); #endif if (pw == NULL) fatal("permanently_set_uid: no user given"); if (temporarily_use_uid_effective) fatal("permanently_set_uid: temporarily_use_uid effective"); debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); #ifdef __APPLE__ /* * OS X requires initgroups after setgid to opt back into * memberd support for >16 supplemental groups. */ if (initgroups(pw->pw_name, pw->pw_gid) < 0) fatal("initgroups %.100s %u: %.100s", pw->pw_name, (u_int)pw->pw_gid, strerror(errno)); #endif if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); #ifndef NO_UID_RESTORATION_TEST /* Try restoration of GID if changed (test clearing of saved gid) */ if (old_gid != pw->pw_gid && pw->pw_uid != 0 && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) fatal("%s: was able to restore old [e]gid", __func__); #endif /* Verify GID drop was successful */ if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", __func__, (u_int)getgid(), (u_int)getegid(), (u_int)pw->pw_gid); } #ifndef NO_UID_RESTORATION_TEST /* Try restoration of UID if changed (test clearing of saved uid) */ if (old_uid != pw->pw_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) fatal("%s: was able to restore old [e]uid", __func__); #endif /* Verify UID drop was successful */ if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", __func__, (u_int)getuid(), (u_int)geteuid(), (u_int)pw->pw_uid); } } openssh-7.2p2/uidswap.h010064400017500001750000000013141267006270000132760ustar00djmdjm/* $OpenBSD: uidswap.h,v 1.13 2006/08/03 03:34:42 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , 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". */ void temporarily_use_uid(struct passwd *); void restore_uid(void); void permanently_set_uid(struct passwd *); void permanently_drop_suid(uid_t); openssh-7.2p2/umac.c010064400017500001750000001327431267006270000125550ustar00djmdjm/* $OpenBSD: umac.c,v 1.11 2014/07/22 07:13:42 guenther Exp $ */ /* ----------------------------------------------------------------------- * * umac.c -- C Implementation UMAC Message Authentication * * Version 0.93b of rfc4418.txt -- 2006 July 18 * * For a full description of UMAC message authentication see the UMAC * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac * Please report bugs and suggestions to the UMAC webpage. * * Copyright (c) 1999-2006 Ted Krovetz * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and with or without fee, is hereby * granted provided that the above copyright notice appears in all copies * and in supporting documentation, and that the name of the copyright * holder not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * Comments should be directed to Ted Krovetz (tdk@acm.org) * * ---------------------------------------------------------------------- */ /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// * * 1) This version does not work properly on messages larger than 16MB * * 2) If you set the switch to use SSE2, then all data must be 16-byte * aligned * * 3) When calling the function umac(), it is assumed that msg is in * a writable buffer of length divisible by 32 bytes. The message itself * does not have to fill the entire buffer, but bytes beyond msg may be * zeroed. * * 4) Three free AES implementations are supported by this implementation of * UMAC. Paulo Barreto's version is in the public domain and can be found * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for * "Barreto"). The only two files needed are rijndael-alg-fst.c and * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU * Public lisence at http://fp.gladman.plus.com/AES/index.htm. It * includes a fast IA-32 assembly version. The OpenSSL crypo library is * the third. * * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes * produced under gcc with optimizations set -O3 or higher. Dunno why. * /////////////////////////////////////////////////////////////////////// */ /* ---------------------------------------------------------------------- */ /* --- User Switches ---------------------------------------------------- */ /* ---------------------------------------------------------------------- */ #ifndef UMAC_OUTPUT_LEN #define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */ #endif #if UMAC_OUTPUT_LEN != 4 && UMAC_OUTPUT_LEN != 8 && \ UMAC_OUTPUT_LEN != 12 && UMAC_OUTPUT_LEN != 16 # error UMAC_OUTPUT_LEN must be defined to 4, 8, 12 or 16 #endif /* #define FORCE_C_ONLY 1 ANSI C and 64-bit integers req'd */ /* #define AES_IMPLEMENTAION 1 1 = OpenSSL, 2 = Barreto, 3 = Gladman */ /* #define SSE2 0 Is SSE2 is available? */ /* #define RUN_TESTS 0 Run basic correctness/speed tests */ /* #define UMAC_AE_SUPPORT 0 Enable auhthenticated encrytion */ /* ---------------------------------------------------------------------- */ /* -- Global Includes --------------------------------------------------- */ /* ---------------------------------------------------------------------- */ #include "includes.h" #include #include #include #include #include #include "xmalloc.h" #include "umac.h" #include "misc.h" /* ---------------------------------------------------------------------- */ /* --- Primitive Data Types --- */ /* ---------------------------------------------------------------------- */ /* The following assumptions may need change on your system */ typedef u_int8_t UINT8; /* 1 byte */ typedef u_int16_t UINT16; /* 2 byte */ typedef u_int32_t UINT32; /* 4 byte */ typedef u_int64_t UINT64; /* 8 bytes */ typedef unsigned int UWORD; /* Register */ /* ---------------------------------------------------------------------- */ /* --- Constants -------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ #define UMAC_KEY_LEN 16 /* UMAC takes 16 bytes of external key */ /* Message "words" are read from memory in an endian-specific manner. */ /* For this implementation to behave correctly, __LITTLE_ENDIAN__ must */ /* be set true if the host computer is little-endian. */ #if BYTE_ORDER == LITTLE_ENDIAN #define __LITTLE_ENDIAN__ 1 #else #define __LITTLE_ENDIAN__ 0 #endif /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Architecture Specific ------------------------------------------ */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Primitive Routines --------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* --- 32-bit by 32-bit to 64-bit Multiplication ------------------------ */ /* ---------------------------------------------------------------------- */ #define MUL64(a,b) ((UINT64)((UINT64)(UINT32)(a) * (UINT64)(UINT32)(b))) /* ---------------------------------------------------------------------- */ /* --- Endian Conversion --- Forcing assembly on some platforms */ /* ---------------------------------------------------------------------- */ #if (__LITTLE_ENDIAN__) #define LOAD_UINT32_REVERSED(p) get_u32(p) #define STORE_UINT32_REVERSED(p,v) put_u32(p,v) #else #define LOAD_UINT32_REVERSED(p) get_u32_le(p) #define STORE_UINT32_REVERSED(p,v) put_u32_le(p,v) #endif #define LOAD_UINT32_LITTLE(p) (get_u32_le(p)) #define STORE_UINT32_BIG(p,v) put_u32(p, v) /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Begin KDF & PDF Section ---------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* UMAC uses AES with 16 byte block and key lengths */ #define AES_BLOCK_LEN 16 /* OpenSSL's AES */ #ifdef WITH_OPENSSL #include "openbsd-compat/openssl-compat.h" #ifndef USE_BUILTIN_RIJNDAEL # include #endif typedef AES_KEY aes_int_key[1]; #define aes_encryption(in,out,int_key) \ AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key) #define aes_key_setup(key,int_key) \ AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key) #else #include "rijndael.h" #define AES_ROUNDS ((UMAC_KEY_LEN / 4) + 6) typedef UINT8 aes_int_key[AES_ROUNDS+1][4][4]; /* AES internal */ #define aes_encryption(in,out,int_key) \ rijndaelEncrypt((u32 *)(int_key), AES_ROUNDS, (u8 *)(in), (u8 *)(out)) #define aes_key_setup(key,int_key) \ rijndaelKeySetupEnc((u32 *)(int_key), (const unsigned char *)(key), \ UMAC_KEY_LEN*8) #endif /* The user-supplied UMAC key is stretched using AES in a counter * mode to supply all random bits needed by UMAC. The kdf function takes * an AES internal key representation 'key' and writes a stream of * 'nbytes' bytes to the memory pointed at by 'bufp'. Each distinct * 'ndx' causes a distinct byte stream. */ static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes) { UINT8 in_buf[AES_BLOCK_LEN] = {0}; UINT8 out_buf[AES_BLOCK_LEN]; UINT8 *dst_buf = (UINT8 *)bufp; int i; /* Setup the initial value */ in_buf[AES_BLOCK_LEN-9] = ndx; in_buf[AES_BLOCK_LEN-1] = i = 1; while (nbytes >= AES_BLOCK_LEN) { aes_encryption(in_buf, out_buf, key); memcpy(dst_buf,out_buf,AES_BLOCK_LEN); in_buf[AES_BLOCK_LEN-1] = ++i; nbytes -= AES_BLOCK_LEN; dst_buf += AES_BLOCK_LEN; } if (nbytes) { aes_encryption(in_buf, out_buf, key); memcpy(dst_buf,out_buf,nbytes); } } /* The final UHASH result is XOR'd with the output of a pseudorandom * function. Here, we use AES to generate random output and * xor the appropriate bytes depending on the last bits of nonce. * This scheme is optimized for sequential, increasing big-endian nonces. */ typedef struct { UINT8 cache[AES_BLOCK_LEN]; /* Previous AES output is saved */ UINT8 nonce[AES_BLOCK_LEN]; /* The AES input making above cache */ aes_int_key prf_key; /* Expanded AES key for PDF */ } pdf_ctx; static void pdf_init(pdf_ctx *pc, aes_int_key prf_key) { UINT8 buf[UMAC_KEY_LEN]; kdf(buf, prf_key, 0, UMAC_KEY_LEN); aes_key_setup(buf, pc->prf_key); /* Initialize pdf and cache */ memset(pc->nonce, 0, sizeof(pc->nonce)); aes_encryption(pc->nonce, pc->cache, pc->prf_key); } static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8]) { /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes * of the AES output. If last time around we returned the ndx-1st * element, then we may have the result in the cache already. */ #if (UMAC_OUTPUT_LEN == 4) #define LOW_BIT_MASK 3 #elif (UMAC_OUTPUT_LEN == 8) #define LOW_BIT_MASK 1 #elif (UMAC_OUTPUT_LEN > 8) #define LOW_BIT_MASK 0 #endif union { UINT8 tmp_nonce_lo[4]; UINT32 align; } t; #if LOW_BIT_MASK != 0 int ndx = nonce[7] & LOW_BIT_MASK; #endif *(UINT32 *)t.tmp_nonce_lo = ((const UINT32 *)nonce)[1]; t.tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */ if ( (((UINT32 *)t.tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) || (((const UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) ) { ((UINT32 *)pc->nonce)[0] = ((const UINT32 *)nonce)[0]; ((UINT32 *)pc->nonce)[1] = ((UINT32 *)t.tmp_nonce_lo)[0]; aes_encryption(pc->nonce, pc->cache, pc->prf_key); } #if (UMAC_OUTPUT_LEN == 4) *((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx]; #elif (UMAC_OUTPUT_LEN == 8) *((UINT64 *)buf) ^= ((UINT64 *)pc->cache)[ndx]; #elif (UMAC_OUTPUT_LEN == 12) ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0]; ((UINT32 *)buf)[2] ^= ((UINT32 *)pc->cache)[2]; #elif (UMAC_OUTPUT_LEN == 16) ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0]; ((UINT64 *)buf)[1] ^= ((UINT64 *)pc->cache)[1]; #endif } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Begin NH Hash Section ------------------------------------------ */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* The NH-based hash functions used in UMAC are described in the UMAC paper * and specification, both of which can be found at the UMAC website. * The interface to this implementation has two * versions, one expects the entire message being hashed to be passed * in a single buffer and returns the hash result immediately. The second * allows the message to be passed in a sequence of buffers. In the * muliple-buffer interface, the client calls the routine nh_update() as * many times as necessary. When there is no more data to be fed to the * hash, the client calls nh_final() which calculates the hash output. * Before beginning another hash calculation the nh_reset() routine * must be called. The single-buffer routine, nh(), is equivalent to * the sequence of calls nh_update() and nh_final(); however it is * optimized and should be prefered whenever the multiple-buffer interface * is not necessary. When using either interface, it is the client's * responsability to pass no more than L1_KEY_LEN bytes per hash result. * * The routine nh_init() initializes the nh_ctx data structure and * must be called once, before any other PDF routine. */ /* The "nh_aux" routines do the actual NH hashing work. They * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines * produce output for all STREAMS NH iterations in one call, * allowing the parallel implementation of the streams. */ #define STREAMS (UMAC_OUTPUT_LEN / 4) /* Number of times hash is applied */ #define L1_KEY_LEN 1024 /* Internal key bytes */ #define L1_KEY_SHIFT 16 /* Toeplitz key shift between streams */ #define L1_PAD_BOUNDARY 32 /* pad message to boundary multiple */ #define ALLOC_BOUNDARY 16 /* Keep buffers aligned to this */ #define HASH_BUF_BYTES 64 /* nh_aux_hb buffer multiple */ typedef struct { UINT8 nh_key [L1_KEY_LEN + L1_KEY_SHIFT * (STREAMS - 1)]; /* NH Key */ UINT8 data [HASH_BUF_BYTES]; /* Incoming data buffer */ int next_data_empty; /* Bookeeping variable for data buffer. */ int bytes_hashed; /* Bytes (out of L1_KEY_LEN) incorperated. */ UINT64 state[STREAMS]; /* on-line state */ } nh_ctx; #if (UMAC_OUTPUT_LEN == 4) static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) /* NH hashing primitive. Previous (partial) hash result is loaded and * then stored via hp pointer. The length of the data pointed at by "dp", * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key * is expected to be endian compensated in memory at key setup. */ { UINT64 h; UWORD c = dlen / 32; UINT32 *k = (UINT32 *)kp; const UINT32 *d = (const UINT32 *)dp; UINT32 d0,d1,d2,d3,d4,d5,d6,d7; UINT32 k0,k1,k2,k3,k4,k5,k6,k7; h = *((UINT64 *)hp); do { d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); h += MUL64((k0 + d0), (k4 + d4)); h += MUL64((k1 + d1), (k5 + d5)); h += MUL64((k2 + d2), (k6 + d6)); h += MUL64((k3 + d3), (k7 + d7)); d += 8; k += 8; } while (--c); *((UINT64 *)hp) = h; } #elif (UMAC_OUTPUT_LEN == 8) static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) /* Same as previous nh_aux, but two streams are handled in one pass, * reading and writing 16 bytes of hash-state per call. */ { UINT64 h1,h2; UWORD c = dlen / 32; UINT32 *k = (UINT32 *)kp; const UINT32 *d = (const UINT32 *)dp; UINT32 d0,d1,d2,d3,d4,d5,d6,d7; UINT32 k0,k1,k2,k3,k4,k5,k6,k7, k8,k9,k10,k11; h1 = *((UINT64 *)hp); h2 = *((UINT64 *)hp + 1); k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); do { d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); h1 += MUL64((k0 + d0), (k4 + d4)); h2 += MUL64((k4 + d0), (k8 + d4)); h1 += MUL64((k1 + d1), (k5 + d5)); h2 += MUL64((k5 + d1), (k9 + d5)); h1 += MUL64((k2 + d2), (k6 + d6)); h2 += MUL64((k6 + d2), (k10 + d6)); h1 += MUL64((k3 + d3), (k7 + d7)); h2 += MUL64((k7 + d3), (k11 + d7)); k0 = k8; k1 = k9; k2 = k10; k3 = k11; d += 8; k += 8; } while (--c); ((UINT64 *)hp)[0] = h1; ((UINT64 *)hp)[1] = h2; } #elif (UMAC_OUTPUT_LEN == 12) static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) /* Same as previous nh_aux, but two streams are handled in one pass, * reading and writing 24 bytes of hash-state per call. */ { UINT64 h1,h2,h3; UWORD c = dlen / 32; UINT32 *k = (UINT32 *)kp; const UINT32 *d = (const UINT32 *)dp; UINT32 d0,d1,d2,d3,d4,d5,d6,d7; UINT32 k0,k1,k2,k3,k4,k5,k6,k7, k8,k9,k10,k11,k12,k13,k14,k15; h1 = *((UINT64 *)hp); h2 = *((UINT64 *)hp + 1); h3 = *((UINT64 *)hp + 2); k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); do { d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15); h1 += MUL64((k0 + d0), (k4 + d4)); h2 += MUL64((k4 + d0), (k8 + d4)); h3 += MUL64((k8 + d0), (k12 + d4)); h1 += MUL64((k1 + d1), (k5 + d5)); h2 += MUL64((k5 + d1), (k9 + d5)); h3 += MUL64((k9 + d1), (k13 + d5)); h1 += MUL64((k2 + d2), (k6 + d6)); h2 += MUL64((k6 + d2), (k10 + d6)); h3 += MUL64((k10 + d2), (k14 + d6)); h1 += MUL64((k3 + d3), (k7 + d7)); h2 += MUL64((k7 + d3), (k11 + d7)); h3 += MUL64((k11 + d3), (k15 + d7)); k0 = k8; k1 = k9; k2 = k10; k3 = k11; k4 = k12; k5 = k13; k6 = k14; k7 = k15; d += 8; k += 8; } while (--c); ((UINT64 *)hp)[0] = h1; ((UINT64 *)hp)[1] = h2; ((UINT64 *)hp)[2] = h3; } #elif (UMAC_OUTPUT_LEN == 16) static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) /* Same as previous nh_aux, but two streams are handled in one pass, * reading and writing 24 bytes of hash-state per call. */ { UINT64 h1,h2,h3,h4; UWORD c = dlen / 32; UINT32 *k = (UINT32 *)kp; const UINT32 *d = (const UINT32 *)dp; UINT32 d0,d1,d2,d3,d4,d5,d6,d7; UINT32 k0,k1,k2,k3,k4,k5,k6,k7, k8,k9,k10,k11,k12,k13,k14,k15, k16,k17,k18,k19; h1 = *((UINT64 *)hp); h2 = *((UINT64 *)hp + 1); h3 = *((UINT64 *)hp + 2); h4 = *((UINT64 *)hp + 3); k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); do { d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15); k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19); h1 += MUL64((k0 + d0), (k4 + d4)); h2 += MUL64((k4 + d0), (k8 + d4)); h3 += MUL64((k8 + d0), (k12 + d4)); h4 += MUL64((k12 + d0), (k16 + d4)); h1 += MUL64((k1 + d1), (k5 + d5)); h2 += MUL64((k5 + d1), (k9 + d5)); h3 += MUL64((k9 + d1), (k13 + d5)); h4 += MUL64((k13 + d1), (k17 + d5)); h1 += MUL64((k2 + d2), (k6 + d6)); h2 += MUL64((k6 + d2), (k10 + d6)); h3 += MUL64((k10 + d2), (k14 + d6)); h4 += MUL64((k14 + d2), (k18 + d6)); h1 += MUL64((k3 + d3), (k7 + d7)); h2 += MUL64((k7 + d3), (k11 + d7)); h3 += MUL64((k11 + d3), (k15 + d7)); h4 += MUL64((k15 + d3), (k19 + d7)); k0 = k8; k1 = k9; k2 = k10; k3 = k11; k4 = k12; k5 = k13; k6 = k14; k7 = k15; k8 = k16; k9 = k17; k10 = k18; k11 = k19; d += 8; k += 8; } while (--c); ((UINT64 *)hp)[0] = h1; ((UINT64 *)hp)[1] = h2; ((UINT64 *)hp)[2] = h3; ((UINT64 *)hp)[3] = h4; } /* ---------------------------------------------------------------------- */ #endif /* UMAC_OUTPUT_LENGTH */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ static void nh_transform(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes) /* This function is a wrapper for the primitive NH hash functions. It takes * as argument "hc" the current hash context and a buffer which must be a * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset * appropriately according to how much message has been hashed already. */ { UINT8 *key; key = hc->nh_key + hc->bytes_hashed; nh_aux(key, buf, hc->state, nbytes); } /* ---------------------------------------------------------------------- */ #if (__LITTLE_ENDIAN__) static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes) /* We endian convert the keys on little-endian computers to */ /* compensate for the lack of big-endian memory reads during hashing. */ { UWORD iters = num_bytes / bpw; if (bpw == 4) { UINT32 *p = (UINT32 *)buf; do { *p = LOAD_UINT32_REVERSED(p); p++; } while (--iters); } else if (bpw == 8) { UINT32 *p = (UINT32 *)buf; UINT32 t; do { t = LOAD_UINT32_REVERSED(p+1); p[1] = LOAD_UINT32_REVERSED(p); p[0] = t; p += 2; } while (--iters); } } #define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z)) #else #define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */ #endif /* ---------------------------------------------------------------------- */ static void nh_reset(nh_ctx *hc) /* Reset nh_ctx to ready for hashing of new data */ { hc->bytes_hashed = 0; hc->next_data_empty = 0; hc->state[0] = 0; #if (UMAC_OUTPUT_LEN >= 8) hc->state[1] = 0; #endif #if (UMAC_OUTPUT_LEN >= 12) hc->state[2] = 0; #endif #if (UMAC_OUTPUT_LEN == 16) hc->state[3] = 0; #endif } /* ---------------------------------------------------------------------- */ static void nh_init(nh_ctx *hc, aes_int_key prf_key) /* Generate nh_key, endian convert and reset to be ready for hashing. */ { kdf(hc->nh_key, prf_key, 1, sizeof(hc->nh_key)); endian_convert_if_le(hc->nh_key, 4, sizeof(hc->nh_key)); nh_reset(hc); } /* ---------------------------------------------------------------------- */ static void nh_update(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes) /* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */ /* even multiple of HASH_BUF_BYTES. */ { UINT32 i,j; j = hc->next_data_empty; if ((j + nbytes) >= HASH_BUF_BYTES) { if (j) { i = HASH_BUF_BYTES - j; memcpy(hc->data+j, buf, i); nh_transform(hc,hc->data,HASH_BUF_BYTES); nbytes -= i; buf += i; hc->bytes_hashed += HASH_BUF_BYTES; } if (nbytes >= HASH_BUF_BYTES) { i = nbytes & ~(HASH_BUF_BYTES - 1); nh_transform(hc, buf, i); nbytes -= i; buf += i; hc->bytes_hashed += i; } j = 0; } memcpy(hc->data + j, buf, nbytes); hc->next_data_empty = j + nbytes; } /* ---------------------------------------------------------------------- */ static void zero_pad(UINT8 *p, int nbytes) { /* Write "nbytes" of zeroes, beginning at "p" */ if (nbytes >= (int)sizeof(UWORD)) { while ((ptrdiff_t)p % sizeof(UWORD)) { *p = 0; nbytes--; p++; } while (nbytes >= (int)sizeof(UWORD)) { *(UWORD *)p = 0; nbytes -= sizeof(UWORD); p += sizeof(UWORD); } } while (nbytes) { *p = 0; nbytes--; p++; } } /* ---------------------------------------------------------------------- */ static void nh_final(nh_ctx *hc, UINT8 *result) /* After passing some number of data buffers to nh_update() for integration * into an NH context, nh_final is called to produce a hash result. If any * bytes are in the buffer hc->data, incorporate them into the * NH context. Finally, add into the NH accumulation "state" the total number * of bits hashed. The resulting numbers are written to the buffer "result". * If nh_update was never called, L1_PAD_BOUNDARY zeroes are incorporated. */ { int nh_len, nbits; if (hc->next_data_empty != 0) { nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); zero_pad(hc->data + hc->next_data_empty, nh_len - hc->next_data_empty); nh_transform(hc, hc->data, nh_len); hc->bytes_hashed += hc->next_data_empty; } else if (hc->bytes_hashed == 0) { nh_len = L1_PAD_BOUNDARY; zero_pad(hc->data, L1_PAD_BOUNDARY); nh_transform(hc, hc->data, nh_len); } nbits = (hc->bytes_hashed << 3); ((UINT64 *)result)[0] = ((UINT64 *)hc->state)[0] + nbits; #if (UMAC_OUTPUT_LEN >= 8) ((UINT64 *)result)[1] = ((UINT64 *)hc->state)[1] + nbits; #endif #if (UMAC_OUTPUT_LEN >= 12) ((UINT64 *)result)[2] = ((UINT64 *)hc->state)[2] + nbits; #endif #if (UMAC_OUTPUT_LEN == 16) ((UINT64 *)result)[3] = ((UINT64 *)hc->state)[3] + nbits; #endif nh_reset(hc); } /* ---------------------------------------------------------------------- */ static void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len, UINT32 unpadded_len, UINT8 *result) /* All-in-one nh_update() and nh_final() equivalent. * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is * well aligned */ { UINT32 nbits; /* Initialize the hash state */ nbits = (unpadded_len << 3); ((UINT64 *)result)[0] = nbits; #if (UMAC_OUTPUT_LEN >= 8) ((UINT64 *)result)[1] = nbits; #endif #if (UMAC_OUTPUT_LEN >= 12) ((UINT64 *)result)[2] = nbits; #endif #if (UMAC_OUTPUT_LEN == 16) ((UINT64 *)result)[3] = nbits; #endif nh_aux(hc->nh_key, buf, result, padded_len); } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Begin UHASH Section -------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* UHASH is a multi-layered algorithm. Data presented to UHASH is first * hashed by NH. The NH output is then hashed by a polynomial-hash layer * unless the initial data to be hashed is short. After the polynomial- * layer, an inner-product hash is used to produce the final UHASH output. * * UHASH provides two interfaces, one all-at-once and another where data * buffers are presented sequentially. In the sequential interface, the * UHASH client calls the routine uhash_update() as many times as necessary. * When there is no more data to be fed to UHASH, the client calls * uhash_final() which * calculates the UHASH output. Before beginning another UHASH calculation * the uhash_reset() routine must be called. The all-at-once UHASH routine, * uhash(), is equivalent to the sequence of calls uhash_update() and * uhash_final(); however it is optimized and should be * used whenever the sequential interface is not necessary. * * The routine uhash_init() initializes the uhash_ctx data structure and * must be called once, before any other UHASH routine. */ /* ---------------------------------------------------------------------- */ /* ----- Constants and uhash_ctx ---------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Poly hash and Inner-Product hash Constants --------------------- */ /* ---------------------------------------------------------------------- */ /* Primes and masks */ #define p36 ((UINT64)0x0000000FFFFFFFFBull) /* 2^36 - 5 */ #define p64 ((UINT64)0xFFFFFFFFFFFFFFC5ull) /* 2^64 - 59 */ #define m36 ((UINT64)0x0000000FFFFFFFFFull) /* The low 36 of 64 bits */ /* ---------------------------------------------------------------------- */ typedef struct uhash_ctx { nh_ctx hash; /* Hash context for L1 NH hash */ UINT64 poly_key_8[STREAMS]; /* p64 poly keys */ UINT64 poly_accum[STREAMS]; /* poly hash result */ UINT64 ip_keys[STREAMS*4]; /* Inner-product keys */ UINT32 ip_trans[STREAMS]; /* Inner-product translation */ UINT32 msg_len; /* Total length of data passed */ /* to uhash */ } uhash_ctx; typedef struct uhash_ctx *uhash_ctx_t; /* ---------------------------------------------------------------------- */ /* The polynomial hashes use Horner's rule to evaluate a polynomial one * word at a time. As described in the specification, poly32 and poly64 * require keys from special domains. The following implementations exploit * the special domains to avoid overflow. The results are not guaranteed to * be within Z_p32 and Z_p64, but the Inner-Product hash implementation * patches any errant values. */ static UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data) { UINT32 key_hi = (UINT32)(key >> 32), key_lo = (UINT32)key, cur_hi = (UINT32)(cur >> 32), cur_lo = (UINT32)cur, x_lo, x_hi; UINT64 X,T,res; X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo); x_lo = (UINT32)X; x_hi = (UINT32)(X >> 32); res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo); T = ((UINT64)x_lo << 32); res += T; if (res < T) res += 59; res += data; if (res < data) res += 59; return res; } /* Although UMAC is specified to use a ramped polynomial hash scheme, this * implementation does not handle all ramp levels. Because we don't handle * the ramp up to p128 modulus in this implementation, we are limited to * 2^14 poly_hash() invocations per stream (for a total capacity of 2^24 * bytes input to UMAC per tag, ie. 16MB). */ static void poly_hash(uhash_ctx_t hc, UINT32 data_in[]) { int i; UINT64 *data=(UINT64*)data_in; for (i = 0; i < STREAMS; i++) { if ((UINT32)(data[i] >> 32) == 0xfffffffful) { hc->poly_accum[i] = poly64(hc->poly_accum[i], hc->poly_key_8[i], p64 - 1); hc->poly_accum[i] = poly64(hc->poly_accum[i], hc->poly_key_8[i], (data[i] - 59)); } else { hc->poly_accum[i] = poly64(hc->poly_accum[i], hc->poly_key_8[i], data[i]); } } } /* ---------------------------------------------------------------------- */ /* The final step in UHASH is an inner-product hash. The poly hash * produces a result not neccesarily WORD_LEN bytes long. The inner- * product hash breaks the polyhash output into 16-bit chunks and * multiplies each with a 36 bit key. */ static UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data) { t = t + ipkp[0] * (UINT64)(UINT16)(data >> 48); t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32); t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16); t = t + ipkp[3] * (UINT64)(UINT16)(data); return t; } static UINT32 ip_reduce_p36(UINT64 t) { /* Divisionless modular reduction */ UINT64 ret; ret = (t & m36) + 5 * (t >> 36); if (ret >= p36) ret -= p36; /* return least significant 32 bits */ return (UINT32)(ret); } /* If the data being hashed by UHASH is no longer than L1_KEY_LEN, then * the polyhash stage is skipped and ip_short is applied directly to the * NH output. */ static void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, u_char *res) { UINT64 t; UINT64 *nhp = (UINT64 *)nh_res; t = ip_aux(0,ahc->ip_keys, nhp[0]); STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]); #if (UMAC_OUTPUT_LEN >= 8) t = ip_aux(0,ahc->ip_keys+4, nhp[1]); STORE_UINT32_BIG((UINT32 *)res+1, ip_reduce_p36(t) ^ ahc->ip_trans[1]); #endif #if (UMAC_OUTPUT_LEN >= 12) t = ip_aux(0,ahc->ip_keys+8, nhp[2]); STORE_UINT32_BIG((UINT32 *)res+2, ip_reduce_p36(t) ^ ahc->ip_trans[2]); #endif #if (UMAC_OUTPUT_LEN == 16) t = ip_aux(0,ahc->ip_keys+12, nhp[3]); STORE_UINT32_BIG((UINT32 *)res+3, ip_reduce_p36(t) ^ ahc->ip_trans[3]); #endif } /* If the data being hashed by UHASH is longer than L1_KEY_LEN, then * the polyhash stage is not skipped and ip_long is applied to the * polyhash output. */ static void ip_long(uhash_ctx_t ahc, u_char *res) { int i; UINT64 t; for (i = 0; i < STREAMS; i++) { /* fix polyhash output not in Z_p64 */ if (ahc->poly_accum[i] >= p64) ahc->poly_accum[i] -= p64; t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]); STORE_UINT32_BIG((UINT32 *)res+i, ip_reduce_p36(t) ^ ahc->ip_trans[i]); } } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* Reset uhash context for next hash session */ static int uhash_reset(uhash_ctx_t pc) { nh_reset(&pc->hash); pc->msg_len = 0; pc->poly_accum[0] = 1; #if (UMAC_OUTPUT_LEN >= 8) pc->poly_accum[1] = 1; #endif #if (UMAC_OUTPUT_LEN >= 12) pc->poly_accum[2] = 1; #endif #if (UMAC_OUTPUT_LEN == 16) pc->poly_accum[3] = 1; #endif return 1; } /* ---------------------------------------------------------------------- */ /* Given a pointer to the internal key needed by kdf() and a uhash context, * initialize the NH context and generate keys needed for poly and inner- * product hashing. All keys are endian adjusted in memory so that native * loads cause correct keys to be in registers during calculation. */ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key) { int i; UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)]; /* Zero the entire uhash context */ memset(ahc, 0, sizeof(uhash_ctx)); /* Initialize the L1 hash */ nh_init(&ahc->hash, prf_key); /* Setup L2 hash variables */ kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */ for (i = 0; i < STREAMS; i++) { /* Fill keys from the buffer, skipping bytes in the buffer not * used by this implementation. Endian reverse the keys if on a * little-endian computer. */ memcpy(ahc->poly_key_8+i, buf+24*i, 8); endian_convert_if_le(ahc->poly_key_8+i, 8, 8); /* Mask the 64-bit keys to their special domain */ ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu; ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */ } /* Setup L3-1 hash variables */ kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */ for (i = 0; i < STREAMS; i++) memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64), 4*sizeof(UINT64)); endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), sizeof(ahc->ip_keys)); for (i = 0; i < STREAMS*4; i++) ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */ /* Setup L3-2 hash variables */ /* Fill buffer with index 4 key */ kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32)); endian_convert_if_le(ahc->ip_trans, sizeof(UINT32), STREAMS * sizeof(UINT32)); } /* ---------------------------------------------------------------------- */ #if 0 static uhash_ctx_t uhash_alloc(u_char key[]) { /* Allocate memory and force to a 16-byte boundary. */ uhash_ctx_t ctx; u_char bytes_to_add; aes_int_key prf_key; ctx = (uhash_ctx_t)malloc(sizeof(uhash_ctx)+ALLOC_BOUNDARY); if (ctx) { if (ALLOC_BOUNDARY) { bytes_to_add = ALLOC_BOUNDARY - ((ptrdiff_t)ctx & (ALLOC_BOUNDARY -1)); ctx = (uhash_ctx_t)((u_char *)ctx + bytes_to_add); *((u_char *)ctx - 1) = bytes_to_add; } aes_key_setup(key,prf_key); uhash_init(ctx, prf_key); } return (ctx); } #endif /* ---------------------------------------------------------------------- */ #if 0 static int uhash_free(uhash_ctx_t ctx) { /* Free memory allocated by uhash_alloc */ u_char bytes_to_sub; if (ctx) { if (ALLOC_BOUNDARY) { bytes_to_sub = *((u_char *)ctx - 1); ctx = (uhash_ctx_t)((u_char *)ctx - bytes_to_sub); } free(ctx); } return (1); } #endif /* ---------------------------------------------------------------------- */ static int uhash_update(uhash_ctx_t ctx, const u_char *input, long len) /* Given len bytes of data, we parse it into L1_KEY_LEN chunks and * hash each one with NH, calling the polyhash on each NH output. */ { UWORD bytes_hashed, bytes_remaining; UINT64 result_buf[STREAMS]; UINT8 *nh_result = (UINT8 *)&result_buf; if (ctx->msg_len + len <= L1_KEY_LEN) { nh_update(&ctx->hash, (const UINT8 *)input, len); ctx->msg_len += len; } else { bytes_hashed = ctx->msg_len % L1_KEY_LEN; if (ctx->msg_len == L1_KEY_LEN) bytes_hashed = L1_KEY_LEN; if (bytes_hashed + len >= L1_KEY_LEN) { /* If some bytes have been passed to the hash function */ /* then we want to pass at most (L1_KEY_LEN - bytes_hashed) */ /* bytes to complete the current nh_block. */ if (bytes_hashed) { bytes_remaining = (L1_KEY_LEN - bytes_hashed); nh_update(&ctx->hash, (const UINT8 *)input, bytes_remaining); nh_final(&ctx->hash, nh_result); ctx->msg_len += bytes_remaining; poly_hash(ctx,(UINT32 *)nh_result); len -= bytes_remaining; input += bytes_remaining; } /* Hash directly from input stream if enough bytes */ while (len >= L1_KEY_LEN) { nh(&ctx->hash, (const UINT8 *)input, L1_KEY_LEN, L1_KEY_LEN, nh_result); ctx->msg_len += L1_KEY_LEN; len -= L1_KEY_LEN; input += L1_KEY_LEN; poly_hash(ctx,(UINT32 *)nh_result); } } /* pass remaining < L1_KEY_LEN bytes of input data to NH */ if (len) { nh_update(&ctx->hash, (const UINT8 *)input, len); ctx->msg_len += len; } } return (1); } /* ---------------------------------------------------------------------- */ static int uhash_final(uhash_ctx_t ctx, u_char *res) /* Incorporate any pending data, pad, and generate tag */ { UINT64 result_buf[STREAMS]; UINT8 *nh_result = (UINT8 *)&result_buf; if (ctx->msg_len > L1_KEY_LEN) { if (ctx->msg_len % L1_KEY_LEN) { nh_final(&ctx->hash, nh_result); poly_hash(ctx,(UINT32 *)nh_result); } ip_long(ctx, res); } else { nh_final(&ctx->hash, nh_result); ip_short(ctx,nh_result, res); } uhash_reset(ctx); return (1); } /* ---------------------------------------------------------------------- */ #if 0 static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res) /* assumes that msg is in a writable buffer of length divisible by */ /* L1_PAD_BOUNDARY. Bytes beyond msg[len] may be zeroed. */ { UINT8 nh_result[STREAMS*sizeof(UINT64)]; UINT32 nh_len; int extra_zeroes_needed; /* If the message to be hashed is no longer than L1_HASH_LEN, we skip * the polyhash. */ if (len <= L1_KEY_LEN) { if (len == 0) /* If zero length messages will not */ nh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ else nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); extra_zeroes_needed = nh_len - len; zero_pad((UINT8 *)msg + len, extra_zeroes_needed); nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result); ip_short(ahc,nh_result, res); } else { /* Otherwise, we hash each L1_KEY_LEN chunk with NH, passing the NH * output to poly_hash(). */ do { nh(&ahc->hash, (UINT8 *)msg, L1_KEY_LEN, L1_KEY_LEN, nh_result); poly_hash(ahc,(UINT32 *)nh_result); len -= L1_KEY_LEN; msg += L1_KEY_LEN; } while (len >= L1_KEY_LEN); if (len) { nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); extra_zeroes_needed = nh_len - len; zero_pad((UINT8 *)msg + len, extra_zeroes_needed); nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result); poly_hash(ahc,(UINT32 *)nh_result); } ip_long(ahc, res); } uhash_reset(ahc); return 1; } #endif /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- Begin UMAC Section --------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* The UMAC interface has two interfaces, an all-at-once interface where * the entire message to be authenticated is passed to UMAC in one buffer, * and a sequential interface where the message is presented a little at a * time. The all-at-once is more optimaized than the sequential version and * should be preferred when the sequential interface is not required. */ struct umac_ctx { uhash_ctx hash; /* Hash function for message compression */ pdf_ctx pdf; /* PDF for hashed output */ void *free_ptr; /* Address to free this struct via */ } umac_ctx; /* ---------------------------------------------------------------------- */ #if 0 int umac_reset(struct umac_ctx *ctx) /* Reset the hash function to begin a new authentication. */ { uhash_reset(&ctx->hash); return (1); } #endif /* ---------------------------------------------------------------------- */ int umac_delete(struct umac_ctx *ctx) /* Deallocate the ctx structure */ { if (ctx) { if (ALLOC_BOUNDARY) ctx = (struct umac_ctx *)ctx->free_ptr; free(ctx); } return (1); } /* ---------------------------------------------------------------------- */ struct umac_ctx *umac_new(const u_char key[]) /* Dynamically allocate a umac_ctx struct, initialize variables, * generate subkeys from key. Align to 16-byte boundary. */ { struct umac_ctx *ctx, *octx; size_t bytes_to_add; aes_int_key prf_key; octx = ctx = xcalloc(1, sizeof(*ctx) + ALLOC_BOUNDARY); if (ctx) { if (ALLOC_BOUNDARY) { bytes_to_add = ALLOC_BOUNDARY - ((ptrdiff_t)ctx & (ALLOC_BOUNDARY - 1)); ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add); } ctx->free_ptr = octx; aes_key_setup(key, prf_key); pdf_init(&ctx->pdf, prf_key); uhash_init(&ctx->hash, prf_key); } return (ctx); } /* ---------------------------------------------------------------------- */ int umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8]) /* Incorporate any pending data, pad, and generate tag */ { uhash_final(&ctx->hash, (u_char *)tag); pdf_gen_xor(&ctx->pdf, (const UINT8 *)nonce, (UINT8 *)tag); return (1); } /* ---------------------------------------------------------------------- */ int umac_update(struct umac_ctx *ctx, const u_char *input, long len) /* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */ /* hash each one, calling the PDF on the hashed output whenever the hash- */ /* output buffer is full. */ { uhash_update(&ctx->hash, input, len); return (1); } /* ---------------------------------------------------------------------- */ #if 0 int umac(struct umac_ctx *ctx, u_char *input, long len, u_char tag[], u_char nonce[8]) /* All-in-one version simply calls umac_update() and umac_final(). */ { uhash(&ctx->hash, input, len, (u_char *)tag); pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag); return (1); } #endif /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ----- End UMAC Section ----------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ openssh-7.2p2/umac.h010064400017500001750000000111241267006270000125470ustar00djmdjm/* $OpenBSD: umac.h,v 1.3 2013/07/22 12:20:02 djm Exp $ */ /* ----------------------------------------------------------------------- * * umac.h -- C Implementation UMAC Message Authentication * * Version 0.93a of rfc4418.txt -- 2006 July 14 * * For a full description of UMAC message authentication see the UMAC * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac * Please report bugs and suggestions to the UMAC webpage. * * Copyright (c) 1999-2004 Ted Krovetz * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and with or without fee, is hereby * granted provided that the above copyright notice appears in all copies * and in supporting documentation, and that the name of the copyright * holder not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * Comments should be directed to Ted Krovetz (tdk@acm.org) * * ---------------------------------------------------------------------- */ /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// * * 1) This version does not work properly on messages larger than 16MB * * 2) If you set the switch to use SSE2, then all data must be 16-byte * aligned * * 3) When calling the function umac(), it is assumed that msg is in * a writable buffer of length divisible by 32 bytes. The message itself * does not have to fill the entire buffer, but bytes beyond msg may be * zeroed. * * 4) Two free AES implementations are supported by this implementation of * UMAC. Paulo Barreto's version is in the public domain and can be found * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for * "Barreto"). The only two files needed are rijndael-alg-fst.c and * rijndael-alg-fst.h. * Brian Gladman's version is distributed with GNU Public lisence * and can be found at http://fp.gladman.plus.com/AES/index.htm. It * includes a fast IA-32 assembly version. * /////////////////////////////////////////////////////////////////////// */ #ifndef HEADER_UMAC_H #define HEADER_UMAC_H #ifdef __cplusplus extern "C" { #endif struct umac_ctx *umac_new(const u_char key[]); /* Dynamically allocate a umac_ctx struct, initialize variables, * generate subkeys from key. */ #if 0 int umac_reset(struct umac_ctx *ctx); /* Reset a umac_ctx to begin authenicating a new message */ #endif int umac_update(struct umac_ctx *ctx, const u_char *input, long len); /* Incorporate len bytes pointed to by input into context ctx */ int umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8]); /* Incorporate any pending data and the ctr value, and return tag. * This function returns error code if ctr < 0. */ int umac_delete(struct umac_ctx *ctx); /* Deallocate the context structure */ #if 0 int umac(struct umac_ctx *ctx, u_char *input, long len, u_char tag[], u_char nonce[8]); /* All-in-one implementation of the functions Reset, Update and Final */ #endif /* uhash.h */ #if 0 typedef struct uhash_ctx *uhash_ctx_t; /* The uhash_ctx structure is defined by the implementation of the */ /* UHASH functions. */ uhash_ctx_t uhash_alloc(u_char key[16]); /* Dynamically allocate a uhash_ctx struct and generate subkeys using */ /* the kdf and kdf_key passed in. If kdf_key_len is 0 then RC6 is */ /* used to generate key with a fixed key. If kdf_key_len > 0 but kdf */ /* is NULL then the first 16 bytes pointed at by kdf_key is used as a */ /* key for an RC6 based KDF. */ int uhash_free(uhash_ctx_t ctx); int uhash_set_params(uhash_ctx_t ctx, void *params); int uhash_reset(uhash_ctx_t ctx); int uhash_update(uhash_ctx_t ctx, u_char *input, long len); int uhash_final(uhash_ctx_t ctx, u_char ouput[]); int uhash(uhash_ctx_t ctx, u_char *input, long len, u_char output[]); #endif /* matching umac-128 API, we reuse umac_ctx, since it's opaque */ struct umac_ctx *umac128_new(const u_char key[]); int umac128_update(struct umac_ctx *ctx, const u_char *input, long len); int umac128_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8]); int umac128_delete(struct umac_ctx *ctx); #ifdef __cplusplus } #endif #endif /* HEADER_UMAC_H */ openssh-7.2p2/uuencode.c010064400017500001750000000057061267006270000134350ustar00djmdjm/* $OpenBSD: uuencode.c,v 1.28 2015/04/24 01:36:24 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 #include #include #include #include #include "xmalloc.h" #include "uuencode.h" /* * Encode binary 'src' of length 'srclength', writing base64-encoded text * to 'target' of size 'targsize'. Will always nul-terminate 'target'. * Returns the number of bytes stored in 'target' or -1 on error (inc. * 'targsize' too small). */ int uuencode(const u_char *src, u_int srclength, char *target, size_t targsize) { return __b64_ntop(src, srclength, target, targsize); } /* * Decode base64-encoded 'src' into buffer 'target' of 'targsize' bytes. * Will skip leading and trailing whitespace. Returns the number of bytes * stored in 'target' or -1 on error (inc. targsize too small). */ int uudecode(const char *src, u_char *target, size_t targsize) { int len; char *encoded, *p; /* copy the 'readonly' source */ encoded = xstrdup(src); /* skip whitespace and data */ for (p = encoded; *p == ' ' || *p == '\t'; p++) ; for (; *p != '\0' && *p != ' ' && *p != '\t'; p++) ; /* and remove trailing whitespace because __b64_pton needs this */ *p = '\0'; len = __b64_pton(encoded, target, targsize); free(encoded); return len; } void dump_base64(FILE *fp, const u_char *data, u_int len) { char *buf; int i, n; if (len > 65536) { fprintf(fp, "dump_base64: len > 65536\n"); return; } buf = xreallocarray(NULL, 2, len); n = uuencode(data, len, buf, 2*len); for (i = 0; i < n; i++) { fprintf(fp, "%c", buf[i]); if (i % 70 == 69) fprintf(fp, "\n"); } if (i % 70 != 69) fprintf(fp, "\n"); free(buf); } openssh-7.2p2/uuencode.h010064400017500001750000000027751267006270000134450ustar00djmdjm/* $OpenBSD: uuencode.h,v 1.14 2010/08/31 11:54:45 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. */ int uuencode(const u_char *, u_int, char *, size_t); int uudecode(const char *, u_char *, size_t); void dump_base64(FILE *, const u_char *, u_int); openssh-7.2p2/verify.c010064400017500001750000000012341267006270000131220ustar00djmdjm/* $OpenBSD: verify.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ /* * Public Domain, Author: Daniel J. Bernstein * Copied from nacl-20110221/crypto_verify/32/ref/verify.c */ #include "includes.h" #include "crypto_api.h" int crypto_verify_32(const unsigned char *x,const unsigned char *y) { unsigned int differentbits = 0; #define F(i) differentbits |= x[i] ^ y[i]; F(0) F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8) F(9) F(10) F(11) F(12) F(13) F(14) F(15) F(16) F(17) F(18) F(19) F(20) F(21) F(22) F(23) F(24) F(25) F(26) F(27) F(28) F(29) F(30) F(31) return (1 & ((differentbits - 1) >> 8)) - 1; } openssh-7.2p2/version.h010064400017500001750000000002521267006270000133070ustar00djmdjm/* $OpenBSD: version.h,v 1.76 2016/02/23 09:14:34 djm Exp $ */ #define SSH_VERSION "OpenSSH_7.2" #define SSH_PORTABLE "p2" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE openssh-7.2p2/xmalloc.c010064400017500001750000000042161267006270000132600ustar00djmdjm/* $OpenBSD: xmalloc.c,v 1.33 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Versions of malloc and friends that check their results, and never return * failure (they call fatal if they encounter an error). * * 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 #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "xmalloc.h" #include "log.h" void ssh_malloc_init(void) { #if defined(__OpenBSD__) extern char *malloc_options; malloc_options = "S"; #endif /* __OpenBSD__ */ } void * xmalloc(size_t size) { void *ptr; if (size == 0) fatal("xmalloc: zero size"); ptr = malloc(size); if (ptr == NULL) fatal("xmalloc: out of memory (allocating %zu bytes)", size); return ptr; } void * xcalloc(size_t nmemb, size_t size) { void *ptr; if (size == 0 || nmemb == 0) fatal("xcalloc: zero size"); if (SIZE_MAX / nmemb < size) fatal("xcalloc: nmemb * size > SIZE_MAX"); ptr = calloc(nmemb, size); if (ptr == NULL) fatal("xcalloc: out of memory (allocating %zu bytes)", size * nmemb); return ptr; } void * xreallocarray(void *ptr, size_t nmemb, size_t size) { void *new_ptr; new_ptr = reallocarray(ptr, nmemb, size); if (new_ptr == NULL) fatal("xreallocarray: out of memory (%zu elements of %zu bytes)", nmemb, size); return new_ptr; } char * xstrdup(const char *str) { size_t len; char *cp; len = strlen(str) + 1; cp = xmalloc(len); strlcpy(cp, str, len); return cp; } int xasprintf(char **ret, const char *fmt, ...) { va_list ap; int i; va_start(ap, fmt); i = vasprintf(ret, fmt, ap); va_end(ap); if (i < 0 || *ret == NULL) fatal("xasprintf: could not allocate memory"); return (i); } openssh-7.2p2/xmalloc.h010064400017500001750000000020361267006270000132630ustar00djmdjm/* $OpenBSD: xmalloc.h,v 1.16 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Created: Mon Mar 20 22:09:17 1995 ylo * * Versions of malloc and friends that check their results, and never return * failure (they call fatal if they encounter an error). * * 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". */ void ssh_malloc_init(void); void *xmalloc(size_t); void *xcalloc(size_t, size_t); void *xreallocarray(void *, size_t, size_t); char *xstrdup(const char *); int xasprintf(char **, const char *, ...) __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2))); openssh-7.2p2/ChangeLog010064400017500001750000010372531267007032500132410ustar00djmdjmcommit 5c35450a0c901d9375fb23343a8dc82397da5f75 Author: Damien Miller Date: Thu Mar 10 05:04:48 2016 +1100 update versions for release commit 9d47b8d3f50c3a6282896df8274147e3b9a38c56 Author: Damien Miller Date: Thu Mar 10 05:03:39 2016 +1100 sanitise characters destined for xauth(1) reported by github.com/tintinweb commit 72b061d4ba0f909501c595d709ea76e06b01e5c9 Author: Darren Tucker Date: Fri Feb 26 14:40:04 2016 +1100 Add a note about using xlc on AIX. commit fd4e4f2416baa2e6565ea49d52aade296bad3e28 Author: Darren Tucker Date: Wed Feb 24 10:44:25 2016 +1100 Skip PrintLastLog in config dump mode. When DISABLE_LASTLOG is set, do not try to include PrintLastLog in the config dump since it'll be reported as UNKNOWN. commit 99135c764fa250801da5ec3b8d06cbd0111caae8 Author: Damien Miller Date: Tue Feb 23 20:17:23 2016 +1100 update spec/README versions ahead of release commit b86a334aaaa4d1e643eb1fd71f718573d6d948b5 Author: Damien Miller Date: Tue Feb 23 20:16:53 2016 +1100 put back portable patchlevel to p1 commit 555dd35ff176847e3c6bd068ba2e8db4022eb24f Author: djm@openbsd.org Date: Tue Feb 23 09:14:34 2016 +0000 upstream commit openssh-7.2 Upstream-ID: 9db776b26014147fc907ece8460ef2bcb0f11e78 commit 1acc058d0a7913838c830ed998a1a1fb5b7864bf Author: Damien Miller Date: Tue Feb 23 16:12:13 2016 +1100 Disable tests where fs perms are incorrect Some tests have strict requirements on the filesystem permissions for certain files and directories. This adds a regress/check-perm tool that copies the relevant logic from sshd to exactly test the paths in question. This lets us skip tests when the local filesystem doesn't conform to our expectations rather than continuing and failing the test run. ok dtucker@ commit 39f303b1f36d934d8410b05625f25c7bcb75db4d Author: Damien Miller Date: Tue Feb 23 12:56:59 2016 +1100 fix sandbox on OSX Lion sshd was failing with: ssh_sandbox_child: sandbox_init: dlopen(/usr/lib/libsandbox.1.dylib, 261):cw image not found [preauth] caused by chroot before sandboxing. Avoid by explicitly linking libsandbox to sshd. Spotted by Darren. commit 0d1451a32c7436e6d3d482351e776bc5e7824ce4 Author: djm@openbsd.org Date: Tue Feb 23 01:34:14 2016 +0000 upstream commit fix spurious error message when incorrect passphrase entered for keys; reported by espie@ ok deraadt@ Upstream-ID: 58b2e46e63ed6912ed1ee780bd3bd8560f9a5899 commit 09d87d79741beb85768b5e788d7dfdf4bc3543dc Author: sobrado@openbsd.org Date: Sat Feb 20 23:06:23 2016 +0000 upstream commit set ssh(1) protocol version to 2 only. ok djm@ Upstream-ID: e168daf9d27d7e392e3c9923826bd8e87b2b3a10 commit 9262e07826ba5eebf8423f7ac9e47ec488c47869 Author: sobrado@openbsd.org Date: Sat Feb 20 23:02:39 2016 +0000 upstream commit add missing ~/.ssh/id_ecdsa and ~/.ssh/id_ed25519 to IdentityFile. ok djm@ Upstream-ID: 6ce99466312e4ae7708017c3665e3edb976f70cf commit c12f0fdce8f985fca8d71829fd64c5b89dc777f5 Author: sobrado@openbsd.org Date: Sat Feb 20 23:01:46 2016 +0000 upstream commit AddressFamily defaults to any. ok djm@ Upstream-ID: 0d94aa06a4b889bf57a7f631c45ba36d24c13e0c commit 907091acb188b1057d50c2158f74c3ecf1c2302b Author: Darren Tucker Date: Fri Feb 19 09:05:39 2016 +1100 Make Solaris privs code build on older systems. Not all systems with Solaris privs have priv_basicset so factor that out and provide backward compatibility code. Similarly, not all have PRIV_NET_ACCESS so wrap that in #ifdef. Based on code from alex at cooperi.net and djm@ with help from carson at taltos.org and wieland at purdue.edu. commit 292a8dee14e5e67dcd1b49ba5c7b9023e8420d59 Author: djm@openbsd.org Date: Wed Feb 17 22:20:14 2016 +0000 upstream commit rekey refactor broke SSH1; spotted by Tom G. Christensen Upstream-ID: 43f0d57928cc077c949af0bfa71ef574dcb58243 commit 3a13cb543df9919aec2fc6b75f3dd3802facaeca Author: djm@openbsd.org Date: Wed Feb 17 08:57:34 2016 +0000 upstream commit rsa-sha2-512,rsa-sha2-256 cannot be selected explicitly in *KeyTypes options yet. Remove them from the lists of algorithms for now. committing on behalf of markus@ ok djm@ Upstream-ID: c6e8820eb8e610ac21551832c0c89684a9a51bb7 commit a685ae8d1c24fb7c712c55a4f3280ee76f5f1e4b Author: jmc@openbsd.org Date: Wed Feb 17 07:38:19 2016 +0000 upstream commit since these pages now clearly tell folks to avoid v1, normalise the docs from a v2 perspective (i.e. stop pointing out which bits are v2 only); ok/tweaks djm ok markus Upstream-ID: eb474f8c36fb6a532dc05c282f7965e38dcfa129 commit c5c3f3279a0e4044b8de71b70d3570d692d0f29d Author: djm@openbsd.org Date: Wed Feb 17 05:29:04 2016 +0000 upstream commit make sandboxed privilege separation the default, not just for new installs; "absolutely" deraadt@ Upstream-ID: 5221ef3b927d2df044e9aa3f5db74ae91743f69b commit eb3f7337a651aa01d5dec019025e6cdc124ed081 Author: jmc@openbsd.org Date: Tue Feb 16 07:47:54 2016 +0000 upstream commit no need to state that protocol 2 is the default twice; Upstream-ID: b1e4c36b0c2e12e338e5b66e2978f2ac953b95eb commit e7901efa9b24e5b0c7e74f2c5520d47eead4d005 Author: djm@openbsd.org Date: Tue Feb 16 05:11:04 2016 +0000 upstream commit Replace list of ciphers and MACs adjacent to -1/-2 flag descriptions in ssh(1) with a strong recommendation not to use protocol 1. Add a similar warning to the Protocol option descriptions in ssh_config(5) and sshd_config(5); prompted by and ok mmcc@ Upstream-ID: 961f99e5437d50e636feca023978950a232ead5e commit 5a0fcb77287342e2fc2ba1cee79b6af108973dc2 Author: djm@openbsd.org Date: Tue Feb 16 03:37:48 2016 +0000 upstream commit add a "Close session" log entry (at loglevel=verbose) to correspond to the existing "Starting session" one. Also include the session id number to make multiplexed sessions more apparent. feedback and ok dtucker@ Upstream-ID: e72d2ac080e02774376325136e532cb24c2e617c commit 624fd395b559820705171f460dd33d67743d13d6 Author: djm@openbsd.org Date: Wed Feb 17 02:24:17 2016 +0000 upstream commit include bad $SSH_CONNECTION in failure output Upstream-Regress-ID: b22d72edfde78c403aaec2b9c9753ef633cc0529 commit 60d860e54b4f199e5e89963b1c086981309753cb Author: Darren Tucker Date: Wed Feb 17 13:37:09 2016 +1100 Rollback addition of va_start. va_start was added in 0f754e29dd3760fc0b172c1220f18b753fb0957e, however it has the wrong number of args and it's not usable in non-variadic functions anyway so it breaks things (for example Solaris 2.6 as reported by Tom G. Christensen).i ok djm@ commit 2fee909c3cee2472a98b26eb82696297b81e0d38 Author: Darren Tucker Date: Wed Feb 17 09:48:15 2016 +1100 Look for gethostbyname in libresolv and libnsl. Should fix build problem on Solaris 2.6 reported by Tom G. Christensen. commit 5ac712d81a84396aab441a272ec429af5b738302 Author: Damien Miller Date: Tue Feb 16 10:45:02 2016 +1100 make existing ssh_malloc_init only for __OpenBSD__ commit 24c9bded569d9f2449ded73f92fb6d12db7a9eec Author: djm@openbsd.org Date: Mon Feb 15 23:32:37 2016 +0000 upstream commit memleak of algorithm name in mm_answer_sign; reported by Jakub Jelen Upstream-ID: ccd742cd25952240ebd23d7d4d6b605862584d08 commit ffb1e7e896139a42ceb78676f637658f44612411 Author: dtucker@openbsd.org Date: Mon Feb 15 09:47:49 2016 +0000 upstream commit Add a function to enable security-related malloc_options. With and ok deraadt@, something similar has been in the snaps for a while. Upstream-ID: 43a95523b832b7f3b943d2908662191110c380ed commit ef39e8c0497ff0564990a4f9e8b7338b3ba3507c Author: Damien Miller Date: Tue Feb 16 10:34:39 2016 +1100 sync ssh-copy-id with upstream 783ef08b0a75 commit d2d772f55b19bb0e8d03c2fe1b9bb176d9779efd Author: djm@openbsd.org Date: Fri Feb 12 00:20:30 2016 +0000 upstream commit avoid fatal() for PKCS11 tokens that present empty key IDs bz#1773, ok markus@ Upstream-ID: 044a764fee526f2c4a9d530bd10695422d01fc54 commit e4c918a6c721410792b287c9fd21356a1bed5805 Author: djm@openbsd.org Date: Thu Feb 11 02:56:32 2016 +0000 upstream commit sync crypto algorithm lists in ssh_config(5) and sshd_config(5) with current reality. bz#2527 Upstream-ID: d7fd1b6c1ed848d866236bcb1d7049d2bb9b2ff6 commit e30cabfa4ab456a30b3224f7f545f1bdfc4a2517 Author: djm@openbsd.org Date: Thu Feb 11 02:21:34 2016 +0000 upstream commit fix regression in openssh-6.8 sftp client: existing destination directories would incorrectly terminate recursive uploads; bz#2528 Upstream-ID: 3306be469f41f26758e3d447987ac6d662623e18 commit 714e367226ded4dc3897078be48b961637350b05 Author: djm@openbsd.org Date: Tue Feb 9 05:30:04 2016 +0000 upstream commit turn off more old crypto in the client: hmac-md5, ripemd, truncated HMACs, RC4, blowfish. ok markus@ dtucker@ Upstream-ID: 96aa11c2c082be45267a690c12f1d2aae6acd46e commit 5a622844ff7f78dcb75e223399f9ef0977e8d0a3 Author: djm@openbsd.org Date: Mon Feb 8 23:40:12 2016 +0000 upstream commit don't attempt to percent_expand() already-canonicalised addresses, avoiding unnecessary failures when attempting to connect to scoped IPv6 addresses (that naturally contain '%' characters) Upstream-ID: f24569cffa1a7cbde5f08dc739a72f4d78aa5c6a commit 19bcf2ea2d17413f2d9730dd2a19575ff86b9b6a Author: djm@openbsd.org Date: Mon Feb 8 10:57:07 2016 +0000 upstream commit refactor activation of rekeying This makes automatic rekeying internal to the packet code (previously the server and client loops needed to assist). In doing to it makes application of rekey limits more accurate by accounting for packets about to be sent as well as packets queued during rekeying events themselves. Based on a patch from dtucker@ which was in turn based on a patch Aleksander Adamowski in bz#2521; ok markus@ Upstream-ID: a441227fd64f9739850ca97b4cf794202860fcd8 commit 603ba41179e4b53951c7b90ee95b6ef3faa3f15d Author: naddy@openbsd.org Date: Fri Feb 5 13:28:19 2016 +0000 upstream commit Only check errno if read() has returned an error. EOF is not an error. This fixes a problem where the mux master would sporadically fail to notice that the client had exited. ok mikeb@ djm@ Upstream-ID: 3c2dadc21fac6ef64665688aac8a75fffd57ae53 commit 56d7dac790693ce420d225119283bc355cff9185 Author: jsg@openbsd.org Date: Fri Feb 5 04:31:21 2016 +0000 upstream commit avoid an uninitialised value when NumberOfPasswordPrompts is 0 ok markus@ djm@ Upstream-ID: 11b068d83c2865343aeb46acf1e9eec00f829b6b commit deae7d52d59c5019c528f977360d87fdda15d20b Author: djm@openbsd.org Date: Fri Feb 5 03:07:06 2016 +0000 upstream commit mention internal DH-GEX fallback groups; bz#2302 Upstream-ID: e7b395fcca3122cd825515f45a2e41c9a157e09e commit cac3b6665f884d46192c0dc98a64112e8b11a766 Author: djm@openbsd.org Date: Fri Feb 5 02:37:56 2016 +0000 upstream commit better description for MaxSessions; bz#2531 Upstream-ID: e2c0d74ee185cd1a3e9d4ca1f1b939b745b354da commit 5ef4b0fdcc7a239577a754829b50022b91ab4712 Author: Damien Miller Date: Wed Jan 27 17:45:56 2016 +1100 avoid FreeBSD RCS Id in comment Change old $FreeBSD version string in comment so it doesn't become an RCS ident downstream; requested by des AT des.no commit 696d12683c90d20a0a9c5f4275fc916b7011fb04 Author: djm@openbsd.org Date: Thu Feb 4 23:43:48 2016 +0000 upstream commit printf argument casts to avoid warnings on strict compilers Upstream-ID: 7b9f6712cef01865ad29070262d366cf13587c9c commit 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a Author: millert@openbsd.org Date: Mon Feb 1 21:18:17 2016 +0000 upstream commit Avoid ugly "DISPLAY "(null)" invalid; disabling X11 forwarding" message when DISPLAY is not set. This could also result in a crash on systems with a printf that doesn't handle NULL. OK djm@ Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412 commit 537f88ec7bcf40bd444ac5584c707c5588c55c43 Author: dtucker@openbsd.org Date: Fri Jan 29 05:18:15 2016 +0000 upstream commit Add regression test for RekeyLimit parsing of >32bit values (4G and 8G). Upstream-Regress-ID: 548390350c62747b6234f522a99c319eee401328 commit 4c6cb8330460f94e6c7ae28a364236d4188156a3 Author: dtucker@openbsd.org Date: Fri Jan 29 23:04:46 2016 +0000 upstream commit Remove leftover roaming dead code. ok djm markus. Upstream-ID: 13d1f9c8b65a5109756bcfd3b74df949d53615be commit 28136471809806d6246ef41e4341467a39fe2f91 Author: djm@openbsd.org Date: Fri Jan 29 05:46:01 2016 +0000 upstream commit include packet type of non-data packets in debug3 output; ok markus dtucker Upstream-ID: 034eaf639acc96459b9c5ce782db9fcd8bd02d41 commit 6fd6e28daccafaa35f02741036abe64534c361a1 Author: dtucker@openbsd.org Date: Fri Jan 29 03:31:03 2016 +0000 upstream commit Revert "account for packets buffered but not yet processed" change as it breaks for very small RekeyLimit values due to continuous rekeying. ok djm@ Upstream-ID: 7e03f636cb45ab60db18850236ccf19079182a19 commit 921ff00b0ac429666fb361d2d6cb1c8fff0006cb Author: dtucker@openbsd.org Date: Fri Jan 29 02:54:45 2016 +0000 upstream commit Allow RekeyLimits in excess of 4G up to 2**63 bits (limited by the return type of scan_scaled). Part of bz#2521, ok djm. Upstream-ID: 13bea82be566b9704821b1ea05bf7804335c7979 commit c0060a65296f01d4634f274eee184c0e93ba0f23 Author: dtucker@openbsd.org Date: Fri Jan 29 02:42:46 2016 +0000 upstream commit Account for packets buffered but not yet processed when computing whether or not it is time to perform rekeying. bz#2521, based loosely on a patch from olo at fb.com, ok djm@ Upstream-ID: 67e268b547f990ed220f3cb70a5624d9bda12b8c commit 44cf930e670488c85c9efeb373fa5f4b455692ac Author: djm@openbsd.org Date: Wed Jan 27 06:44:58 2016 +0000 upstream commit change old $FreeBSD version string in comment so it doesn't become an RCS ident downstream; requested by des AT des.no Upstream-ID: 8ca558c01f184e596b45e4fc8885534b2c864722 commit ebacd377769ac07d1bf3c75169644336056b7060 Author: djm@openbsd.org Date: Wed Jan 27 00:53:12 2016 +0000 upstream commit make the debug messages a bit more useful here Upstream-ID: 478ccd4e897e0af8486b294aa63aa3f90ab78d64 commit 458abc2934e82034c5c281336d8dc0f910aecad3 Author: jsg@openbsd.org Date: Sat Jan 23 05:31:35 2016 +0000 upstream commit Zero a stack buffer with explicit_bzero() instead of memset() when returning from client_loop() for consistency with buffer_free()/sshbuf_free(). ok dtucker@ deraadt@ djm@ Upstream-ID: bc9975b2095339811c3b954694d7d15ea5c58f66 commit 65a3c0dacbc7dbb75ddb6a70ebe22d8de084d0b0 Author: dtucker@openbsd.org Date: Wed Jan 20 09:22:39 2016 +0000 upstream commit Include sys/time.h for gettimeofday. From sortie at maxsi.org. Upstream-ID: 6ed0c33b836d9de0a664cd091e86523ecaa2fb3b commit fc77ccdc2ce6d5d06628b8da5048a6a5f6ffca5a Author: markus@openbsd.org Date: Thu Jan 14 22:56:56 2016 +0000 upstream commit fd leaks; report Qualys Security Advisory team; ok deraadt@ Upstream-ID: 4ec0f12b9d8fa202293c9effa115464185aa071d commit a306863831c57ec5fad918687cc5d289ee8e2635 Author: markus@openbsd.org Date: Thu Jan 14 16:17:39 2016 +0000 upstream commit remove roaming support; ok djm@ Upstream-ID: 2cab8f4b197bc95776fb1c8dc2859dad0c64dc56 commit 6ef49e83e30688504552ac10875feabd5521565f Author: deraadt@openbsd.org Date: Thu Jan 14 14:34:34 2016 +0000 upstream commit Disable experimental client-side roaming support. Server side was disabled/gutted for years already, but this aspect was surprisingly forgotten. Thanks for report from Qualys Upstream-ID: 2328004b58f431a554d4c1bf67f5407eae3389df commit 8d7b523b96d3be180572d9d338cedaafc0570f60 Author: Damien Miller Date: Thu Jan 14 11:08:19 2016 +1100 bump version numbers commit 8c3d512a1fac8b9c83b4d0c9c3f2376290bd84ca Author: Damien Miller Date: Thu Jan 14 11:04:04 2016 +1100 openssh-7.1p2 commit e6c85f8889c5c9eb04796fdb76d2807636b9eef5 Author: Damien Miller Date: Fri Jan 15 01:30:36 2016 +1100 forcibly disable roaming support in the client commit ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c Author: djm@openbsd.org Date: Wed Jan 13 23:04:47 2016 +0000 upstream commit eliminate fallback from untrusted X11 forwarding to trusted forwarding when the X server disables the SECURITY extension; Reported by Thomas Hoger; ok deraadt@ Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 commit 9a728cc918fad67c8a9a71201088b1e150340ba4 Author: djm@openbsd.org Date: Tue Jan 12 23:42:54 2016 +0000 upstream commit use explicit_bzero() more liberally in the buffer code; ok deraadt Upstream-ID: 0ece37069fd66bc6e4f55eb1321f93df372b65bf commit 4626cbaf78767fc8e9c86dd04785386c59ae0839 Author: Damien Miller Date: Fri Jan 8 14:24:56 2016 +1100 Support Illumos/Solaris fine-grained privileges Includes a pre-auth privsep sandbox and several pledge() emulations. bz#2511, patch by Alex Wilson. ok dtucker@ commit 422d1b3ee977ff4c724b597fb2e437d38fc8de9d Author: djm@openbsd.org Date: Thu Dec 31 00:33:52 2015 +0000 upstream commit fix three bugs in KRL code related to (unused) signature support: verification length was being incorrectly calculated, multiple signatures were being incorrectly processed and a NULL dereference that occurred when signatures were verified. Reported by Carl Jackson Upstream-ID: e705e97ad3ccce84291eaa651708dd1b9692576b commit 6074c84bf95d00f29cc7d5d3cd3798737851aa1a Author: djm@openbsd.org Date: Wed Dec 30 23:46:14 2015 +0000 upstream commit unused prototype Upstream-ID: f3eef4389d53ed6c0d5c77dcdcca3060c745da97 commit 6213f0e180e54122bb1ba928e11c784e2b4e5380 Author: guenther@openbsd.org Date: Sat Dec 26 20:51:35 2015 +0000 upstream commit Use pread/pwrite instead separate lseek+read/write for lastlog. Cast to off_t before multiplication to avoid truncation on ILP32 ok kettenis@ mmcc@ Upstream-ID: fc40092568cd195719ddf1a00aa0742340d616cf commit d7d2bc95045a43dd56ea696cc1d030ac9d77e81f Author: semarie@openbsd.org Date: Sat Dec 26 07:46:03 2015 +0000 upstream commit adjust pledge promises for ControlMaster: when using "ask" or "autoask", the process will use ssh-askpass for asking confirmation. problem found by halex@ ok halex@ Upstream-ID: 38a58b30ae3eef85051c74d3c247216ec0735f80 commit 271df8185d9689b3fb0523f58514481b858f6843 Author: djm@openbsd.org Date: Sun Dec 13 22:42:23 2015 +0000 upstream commit unbreak connections with peers that set first_kex_follows; fix from Matt Johnston va bz#2515 Upstream-ID: decc88ec4fc7515594fdb42b04aa03189a44184b commit 43849a47c5f8687699eafbcb5604f6b9c395179f Author: doug@openbsd.org Date: Fri Dec 11 17:41:37 2015 +0000 upstream commit Add "id" to ssh-agent pledge for subprocess support. Found the hard way by Jan Johansson when using ssh-agent with X. Also, rearranged proc/exec and retval to match other pledge calls in the tree. ok djm@ Upstream-ID: 914255f6850e5e7fa830a2de6c38605333b584db commit 52d7078421844b2f88329f5be3de370b0a938636 Author: mmcc@openbsd.org Date: Fri Dec 11 04:21:11 2015 +0000 upstream commit Remove NULL-checks before sshbuf_free(). ok djm@ Upstream-ID: 5ebed00ed5f9f03b119a345085e8774565466917 commit a4b9e0f4e4a6980a0eb8072f76ea611cab5b77e7 Author: djm@openbsd.org Date: Fri Dec 11 03:24:25 2015 +0000 upstream commit include remote port number in a few more messages; makes tying log messages together into a session a bit easier; bz#2503 ok dtucker@ Upstream-ID: 9300dc354015f7a7368d94a8ff4a4266a69d237e commit 6091c362e89079397e68744ae30df121b0a72c07 Author: djm@openbsd.org Date: Fri Dec 11 03:20:09 2015 +0000 upstream commit don't try to load SSHv1 private key when compiled without SSHv1 support. From Iain Morgan bz#2505 Upstream-ID: 8b8e7b02a448cf5e5635979df2d83028f58868a7 commit cce6a36bb95e81fa8bfb46daf22eabcf13afc352 Author: djm@openbsd.org Date: Fri Dec 11 03:19:09 2015 +0000 upstream commit use SSH_MAX_PUBKEY_BYTES consistently as buffer size when reading key files. Increase it to match the size of the buffers already being used. Upstream-ID: 1b60586b484b55a947d99a0b32bd25e0ced56fae commit 89540b6de025b80404a0cb8418c06377f3f98848 Author: mmcc@openbsd.org Date: Fri Dec 11 02:31:47 2015 +0000 upstream commit Remove NULL-checks before sshkey_free(). ok djm@ Upstream-ID: 3e35afe8a25e021216696b5d6cde7f5d2e5e3f52 commit 79394ed6d74572c2d2643d73937dad33727fc240 Author: dtucker@openbsd.org Date: Fri Dec 11 02:29:03 2015 +0000 upstream commit fflush stdout so that output is seen even when running in debug mode when output may otherwise not be flushed. Patch from dustin at null-ptr.net. Upstream-ID: b0c6b4cd2cdb01d7e9eefbffdc522e35b5bc4acc commit ee607cccb6636eb543282ba90e0677b0604d8b7a Author: Darren Tucker Date: Tue Dec 15 15:23:49 2015 +1100 Increase robustness of redhat/openssh.spec - remove configure --with-rsh, because this option isn't supported anymore - replace last occurrence of BuildPreReq by BuildRequires - update grep statement to query the krb5 include directory Patch from CarstenGrohmann via github, ok djm. commit b5fa0cd73555b991a543145603658d7088ec6b60 Author: Darren Tucker Date: Tue Dec 15 15:10:32 2015 +1100 Allow --without-ssl-engine with --without-openssl Patch from Mike Frysinger via github. commit c1d7e546f6029024f3257cc25c92f2bddf163125 Author: Darren Tucker Date: Tue Dec 15 14:27:09 2015 +1100 Include openssl crypto.h for SSLeay. Patch from doughdemon via github. commit c6f5f01651526e88c00d988ce59d71f481ebac62 Author: Darren Tucker Date: Tue Dec 15 13:59:12 2015 +1100 Add sys/time.h for gettimeofday. Should allow it it compile with MUSL libc. Based on patch from doughdemon via github. commit 39736be06c7498ef57d6970f2d85cf066ae57c82 Author: djm@openbsd.org Date: Fri Dec 11 02:20:28 2015 +0000 upstream commit correct error messages; from Tomas Kuthan bz#2507 Upstream-ID: 7454a0affeab772398052954c79300aa82077093 commit 94141b7ade24afceeb6762a3f99e09e47a6c42b6 Author: mmcc@openbsd.org Date: Fri Dec 11 00:20:04 2015 +0000 upstream commit Pass (char *)NULL rather than (char *)0 to execl and execlp. ok dtucker@ Upstream-ID: 56c955106cbddba86c3dd9bbf786ac0d1b361492 commit d59ce08811bf94111c2f442184cf7d1257ffae24 Author: mmcc@openbsd.org Date: Thu Dec 10 17:08:40 2015 +0000 upstream commit Remove NULL-checks before free(). ok dtucker@ Upstream-ID: e3d3cb1ce900179906af36517b5eea0fb15e6ef8 commit 8e56dd46cb37879c73bce2d6032cf5e7f82d5a71 Author: mmcc@openbsd.org Date: Thu Dec 10 07:01:35 2015 +0000 upstream commit Fix a couple "the the" typos. ok dtucker@ Upstream-ID: ec364c5af32031f013001fd28d1bd3dfacfe9a72 commit 6262a0522ddc2c0f2e9358dcb68d59b46e9c533e Author: markus@openbsd.org Date: Mon Dec 7 20:04:09 2015 +0000 upstream commit stricter encoding type checks for ssh-rsa; ok djm@ Upstream-ID: 8cca7c787599a5e8391e184d0b4f36fdc3665650 commit d86a3ba7af160c13496102aed861ae48a4297072 Author: Damien Miller Date: Wed Dec 9 09:18:45 2015 +1100 Don't set IPV6_V6ONLY on OpenBSD It isn't necessary and runs afoul of pledge(2) restrictions. commit da98c11d03d819a15429d8fff9688acd7505439f Author: djm@openbsd.org Date: Mon Dec 7 02:20:46 2015 +0000 upstream commit basic unit tests for rsa-sha2-* signature types Upstream-Regress-ID: 7dc4b9db809d578ff104d591b4d86560c3598d3c commit 3da893fdec9936dd2c23739cdb3c0c9d4c59fca0 Author: markus@openbsd.org Date: Sat Dec 5 20:53:21 2015 +0000 upstream commit prefer rsa-sha2-512 over -256 for hostkeys, too; noticed by naddy@ Upstream-ID: 685f55f7ec566a8caca587750672723a0faf3ffe commit 8b56e59714d87181505e4678f0d6d39955caf10e Author: tobias@openbsd.org Date: Fri Dec 4 21:51:06 2015 +0000 upstream commit Properly handle invalid %-format by calling fatal. ok deraadt, djm Upstream-ID: 5692bce7d9f6eaa9c488cb93d3b55e758bef1eac commit 76c9fbbe35aabc1db977fb78e827644345e9442e Author: markus@openbsd.org Date: Fri Dec 4 16:41:28 2015 +0000 upstream commit implement SHA2-{256,512} for RSASSA-PKCS1-v1_5 signatures (user and host auth) based on draft-rsa-dsa-sha2-256-03.txt and draft-ssh-ext-info-04.txt; with & ok djm@ Upstream-ID: cf82ce532b2733e5c4b34bb7b7c94835632db309 commit 6064a8b8295cb5a17b5ebcfade53053377714f40 Author: djm@openbsd.org Date: Fri Dec 4 00:24:55 2015 +0000 upstream commit clean up agent_fd handling; properly initialise it to -1 and make tests consistent ok markus@ Upstream-ID: ac9554323d5065745caf17b5e37cb0f0d4825707 commit b91926a97620f3e51761c271ba57aa5db790f48d Author: semarie@openbsd.org Date: Thu Dec 3 17:00:18 2015 +0000 upstream commit pledges ssh client: - mux client: which is used when ControlMaster is in use. will end with "stdio proc tty" (proc is to permit sending SIGWINCH to mux master on window resize) - client loop: several levels of pledging depending of your used options ok deraadt@ Upstream-ID: 21676155a700e51f2ce911e33538e92a2cd1d94b commit bcce47466bbc974636f588b5e4a9a18ae386f64a Author: doug@openbsd.org Date: Wed Dec 2 08:30:50 2015 +0000 upstream commit Add "cpath" to the ssh-agent pledge so the cleanup handler can unlink(). ok djm@ Upstream-ID: 9e632991d48241d56db645602d381253a3d8c29d commit a90d001543f46716b6590c6dcc681d5f5322f8cf Author: djm@openbsd.org Date: Wed Dec 2 08:00:58 2015 +0000 upstream commit ssh-agent pledge needs proc for askpass; spotted by todd@ Upstream-ID: 349aa261b29cc0e7de47ef56167769c432630b2a commit d952162b3c158a8f23220587bb6c8fcda75da551 Author: djm@openbsd.org Date: Tue Dec 1 23:29:24 2015 +0000 upstream commit basic pledge() for ssh-agent, more refinement needed Upstream-ID: 5b5b03c88162fce549e45e1b6dd833f20bbb5e13 commit f0191d7c8e76e30551084b79341886d9bb38e453 Author: Damien Miller Date: Mon Nov 30 10:53:25 2015 +1100 Revert "stub for pledge(2) for systems that lack it" This reverts commit 14c887c8393adde2d9fd437d498be30f8c98535c. dtucker beat me to it :/ commit 6283cc72eb0e49a3470d30e07ca99a1ba9e89676 Author: Damien Miller Date: Mon Nov 30 10:37:03 2015 +1100 revert 7d4c7513: bring back S/Key prototypes (but leave RCSID changes) commit 14c887c8393adde2d9fd437d498be30f8c98535c Author: Damien Miller Date: Mon Nov 30 09:45:29 2015 +1100 stub for pledge(2) for systems that lack it commit 452c0b6af5d14c37553e30059bf74456012493f3 Author: djm@openbsd.org Date: Sun Nov 29 22:18:37 2015 +0000 upstream commit pledge, better fatal() messages; feedback deraadt@ Upstream-ID: 3e00f6ccfe2b9a7a2d1dbba5409586180801488f commit 6da413c085dba37127687b2617a415602505729b Author: deraadt@openbsd.org Date: Sat Nov 28 06:50:52 2015 +0000 upstream commit do not leak temp file if there is no known_hosts file from craig leres, ok djm Upstream-ID: c820497fd5574844c782e79405c55860f170e426 commit 3ddd15e1b63a4d4f06c8ab16fbdd8a5a61764f16 Author: Darren Tucker Date: Mon Nov 30 07:23:53 2015 +1100 Add a null implementation of pledge. Fixes builds on almost everything. commit b1d6b3971ef256a08692efc409fc9ada719111cc Author: djm@openbsd.org Date: Sat Nov 28 06:41:03 2015 +0000 upstream commit don't include port number in tcpip-forward replies for requests that don't allocate a port; bz#2509 diagnosed by Ron Frederick ok markus Upstream-ID: 77efad818addb61ec638b5a2362f1554e21a970a commit 9080bd0b9cf10d0f13b1f642f20cb84285cb8d65 Author: deraadt@openbsd.org Date: Fri Nov 27 00:49:31 2015 +0000 upstream commit pledge "stdio rpath wpath cpath fattr tty proc exec" except for the -p option (which sadly has insane semantics...) ok semarie dtucker Upstream-ID: 8854bbd58279abe00f6c33f8094bdc02c8c65059 commit 4d90625b229cf6b3551d81550a9861897509a65f Author: halex@openbsd.org Date: Fri Nov 20 23:04:01 2015 +0000 upstream commit allow comment change for all supported formats ok djm@ Upstream-ID: 5fc477cf2f119b2d44aa9c683af16cb00bb3744b commit 8ca915fc761519dd1f7766a550ec597a81db5646 Author: djm@openbsd.org Date: Fri Nov 20 01:45:29 2015 +0000 upstream commit add cast to make -Werror clean Upstream-ID: 288db4f8f810bd475be01320c198250a04ff064d commit ac9473580dcd401f8281305af98635cdaae9bf96 Author: Damien Miller Date: Fri Nov 20 12:35:41 2015 +1100 fix multiple authentication using S/Key w/ privsep bz#2502, patch from Kevin Korb and feandil_ commit 88b6fcdeb87a2fb76767854d9eb15006662dca57 Author: djm@openbsd.org Date: Thu Nov 19 08:23:27 2015 +0000 upstream commit ban ConnectionAttempts=0, it makes no sense and would cause ssh_connect_direct() to print an uninitialised stack variable; bz#2500 reported by dvw AT phas.ubc.ca Upstream-ID: 32b5134c608270583a90b93a07b3feb3cbd5f7d5 commit 964ab3ee7a8f96bdbc963d5b5a91933d6045ebe7 Author: djm@openbsd.org Date: Thu Nov 19 01:12:32 2015 +0000 upstream commit trailing whitespace Upstream-ID: 31fe0ad7c4d08e87f1d69c79372f5e3c5cd79051 commit f96516d052dbe38561f6b92b0e4365d8e24bb686 Author: djm@openbsd.org Date: Thu Nov 19 01:09:38 2015 +0000 upstream commit print host certificate contents at debug level Upstream-ID: 39354cdd8a2b32b308fd03f98645f877f540f00d commit 499cf36fecd6040e30e2912dd25655bc574739a7 Author: djm@openbsd.org Date: Thu Nov 19 01:08:55 2015 +0000 upstream commit move the certificate validity formatting code to sshkey.[ch] Upstream-ID: f05f7c78fab20d02ff1d5ceeda533ef52e8fe523 commit bcb7bc77bbb1535d1008c7714085556f3065d99d Author: djm@openbsd.org Date: Wed Nov 18 08:37:28 2015 +0000 upstream commit fix "ssh-keygen -l" of private key, broken in support for multiple plain keys on stdin Upstream-ID: 6b3132d2c62d03d0bad6f2bcd7e2d8b7dab5cd9d commit 259adb6179e23195c8f6913635ea71040d1ccd63 Author: millert@openbsd.org Date: Mon Nov 16 23:47:52 2015 +0000 upstream commit Replace remaining calls to index(3) with strchr(3). OK jca@ krw@ Upstream-ID: 33837d767a0cf1db1489b96055f9e330bc0bab6d commit c56a255162c2166884539c0a1f7511575325b477 Author: djm@openbsd.org Date: Mon Nov 16 22:53:07 2015 +0000 upstream commit Allow fingerprinting from standard input "ssh-keygen -lf -" Support fingerprinting multiple plain keys in a file and authorized_keys files too (bz#1319) ok markus@ Upstream-ID: 903f8b4502929d6ccf53509e4e07eae084574b77 commit 5b4010d9b923cf1b46c9c7b1887c013c2967e204 Author: djm@openbsd.org Date: Mon Nov 16 22:51:05 2015 +0000 upstream commit always call privsep_preauth_child() regardless of whether sshd was started by root; it does important priming before sandboxing and failing to call it could result in sandbox violations later; ok markus@ Upstream-ID: c8a6d0d56c42f3faab38460dc917ca0d1705d383 commit 3a9f84b58b0534bbb485f1eeab75665e2d03371f Author: djm@openbsd.org Date: Mon Nov 16 22:50:01 2015 +0000 upstream commit improve sshkey_read() semantics; only update *cpp when a key is successfully read; ok markus@ Upstream-ID: f371e78e8f4fab366cf69a42bdecedaed5d1b089 commit db6f8dc5dd5655b59368efd074994d4568bc3556 Author: logan@openbsd.org Date: Mon Nov 16 06:13:04 2015 +0000 upstream commit 1) Use xcalloc() instead of xmalloc() to check for potential overflow. (Feedback from both mmcc@ and djm@) 2) move set_size just before the for loop. (suggested by djm@) OK djm@ Upstream-ID: 013534c308187284756c3141f11d2c0f33c47213 commit 383f10fb84a0fee3c01f9d97594f3e22aa3cd5e0 Author: djm@openbsd.org Date: Mon Nov 16 00:30:02 2015 +0000 upstream commit Add a new authorized_keys option "restrict" that includes all current and future key restrictions (no-*-forwarding, etc). Also add permissive versions of the existing restrictions, e.g. "no-pty" -> "pty". This simplifies the task of setting up restricted keys and ensures they are maximally-restricted, regardless of any permissions we might implement in the future. Example: restrict,pty,command="nethack" ssh-ed25519 AAAAC3NzaC1lZDI1... Idea from Jann Horn; ok markus@ Upstream-ID: 04ceb9d448e46e67e13887a7ae5ea45b4f1719d0 commit e41a071f7bda6af1fb3f081bed0151235fa61f15 Author: jmc@openbsd.org Date: Sun Nov 15 23:58:04 2015 +0000 upstream commit correct section number for ssh-agent; Upstream-ID: 44be72fd8bcc167635c49b357b1beea8d5674bd6 commit 1a11670286acddcc19f5eff0966c380831fc4638 Author: jmc@openbsd.org Date: Sun Nov 15 23:54:15 2015 +0000 upstream commit do not confuse mandoc by presenting "Dd"; Upstream-ID: 1470fce171c47b60bbc7ecd0fc717a442c2cfe65 commit f361df474c49a097bfcf16d1b7b5c36fcd844b4b Author: jcs@openbsd.org Date: Sun Nov 15 22:26:49 2015 +0000 upstream commit Add an AddKeysToAgent client option which can be set to 'yes', 'no', 'ask', or 'confirm', and defaults to 'no'. When enabled, a private key that is used during authentication will be added to ssh-agent if it is running (with confirmation enabled if set to 'confirm'). Initial version from Joachim Schipper many years ago. ok markus@ Upstream-ID: a680db2248e8064ec55f8be72d539458c987d5f4 commit d87063d9baf5479b6e813d47dfb694a97df6f6f5 Author: djm@openbsd.org Date: Fri Nov 13 04:39:35 2015 +0000 upstream commit send SSH2_MSG_UNIMPLEMENTED replies to unexpected messages during KEX; bz#2949, ok dtucker@ Upstream-ID: 2b3abdff344d53c8d505f45c83a7b12e84935786 commit 9fd04681a1e9b0af21e08ff82eb674cf0a499bfc Author: djm@openbsd.org Date: Fri Nov 13 04:38:06 2015 +0000 upstream commit Support "none" as an argument for sshd_config ForceCommand and ChrootDirectory. Useful inside Match blocks to override a global default. bz#2486 ok dtucker@ Upstream-ID: 7ef478d6592bc7db5c7376fc33b4443e63dccfa5 commit 94bc0b72c29e511cbbc5772190d43282e5acfdfe Author: djm@openbsd.org Date: Fri Nov 13 04:34:15 2015 +0000 upstream commit support multiple certificates (one per line) and reading from standard input (using "-f -") for "ssh-keygen -L"; ok dtucker@ Upstream-ID: ecbadeeef3926e5be6281689b7250a32a80e88db commit b6b9108f5b561c83612cb97ece4134eb59fde071 Author: djm@openbsd.org Date: Fri Nov 13 02:57:46 2015 +0000 upstream commit list a couple more options usable in Match blocks; bz#2489 Upstream-ID: e4d03f39d254db4c0cc54101921bb89fbda19879 commit a7994b3f5a5a5a33b52b0a6065d08e888f0a99fb Author: djm@openbsd.org Date: Wed Nov 11 04:56:39 2015 +0000 upstream commit improve PEEK/POKE macros: better casts, don't multiply evaluate arguments; ok deraadt@ Upstream-ID: 9a1889e19647615ededbbabab89064843ba92d3e commit 7d4c7513a7f209cb303a608ac6e46b3f1dfc11ec Author: djm@openbsd.org Date: Wed Nov 11 01:48:01 2015 +0000 upstream commit remove prototypes for long-gone s/key support; ok dtucker@ Upstream-ID: db5bed3c57118af986490ab23d399df807359a79 commit 07889c75926c040b8e095949c724e66af26441cb Author: Damien Miller Date: Sat Nov 14 18:44:49 2015 +1100 read back from libcrypto RAND when privdropping makes certain libcrypto implementations cache a /dev/urandom fd in preparation of sandboxing. Based on patch by Greg Hartman. commit 1560596f44c01bb0cef977816410950ed17b8ecd Author: Darren Tucker Date: Tue Nov 10 11:14:47 2015 +1100 Fix compiler warnings in the openssl header check. Noted by Austin English. commit e72a8575ffe1d8adff42c9abe9ca36938acc036b Author: jmc@openbsd.org Date: Sun Nov 8 23:24:03 2015 +0000 upstream commit -c before -H, in SYNOPSIS and usage(); Upstream-ID: 25e8c58a69e1f37fcd54ac2cd1699370acb5e404 commit 3a424cdd21db08c7b0ded902f97b8f02af5aa485 Author: djm@openbsd.org Date: Sun Nov 8 22:30:20 2015 +0000 upstream commit Add "ssh-keyscan -c ..." flag to allow fetching certificates instead of plain keys; ok markus@ Upstream-ID: 0947e2177dba92339eced9e49d3c5bf7dda69f82 commit 69fead5d7cdaa73bdece9fcba80f8e8e70b90346 Author: jmc@openbsd.org Date: Sun Nov 8 22:08:38 2015 +0000 upstream commit remove slogin links; ok deraadt markus djm Upstream-ID: 39ba08548acde4c54f2d4520c202c2a863a3c730 commit 2fecfd486bdba9f51b3a789277bb0733ca36e1c0 Author: djm@openbsd.org Date: Sun Nov 8 21:59:11 2015 +0000 upstream commit fix OOB read in packet code caused by missing return statement found by Ben Hawkes; ok markus@ deraadt@ Upstream-ID: a3e3a85434ebfa0690d4879091959591f30efc62 commit 5e288923a303ca672b686908320bc5368ebec6e6 Author: mmcc@openbsd.org Date: Fri Nov 6 00:31:41 2015 +0000 upstream commit 1. rlogin and rsh are long gone 2. protocol version isn't of core relevance here, and v1 is going away ok markus@, deraadt@ Upstream-ID: 8b46bc94cf1ca7c8c1a75b1c958b2bb38d7579c8 commit 8b29008bbe97f33381d9b4b93fcfa304168d0286 Author: jmc@openbsd.org Date: Thu Nov 5 09:48:05 2015 +0000 upstream commit "commandline" -> "command line", since there are so few examples of the former in the pages, so many of the latter, and in some of these pages we had multiple spellings; prompted by tj Upstream-ID: 78459d59bff74223f8139d9001ccd56fc4310659 commit 996b24cebf20077fbe5db07b3a2c20c2d9db736e Author: Darren Tucker Date: Thu Oct 29 20:57:34 2015 +1100 (re)wrap SYS_sendsyslog in ifdef. Replace ifdef that went missing in commit c61b42f2678f21f05653ac2d3d241b48ab5d59ac. Fixes build on older OpenBSDs. commit b67e2e76fcf1ae7c802eb27ca927e16c91a513ff Author: djm@openbsd.org Date: Thu Oct 29 08:05:17 2015 +0000 upstream commit regress test for "PubkeyAcceptedKeyTypes +..." inside a Match block Upstream-Regress-ID: 246c37ed64a2e5704d4c158ccdca1ff700e10647 commit abd9dbc3c0d8c8c7561347cfa22166156e78c077 Author: dtucker@openbsd.org Date: Mon Oct 26 02:50:58 2015 +0000 upstream commit Fix typo certopt->certopts in shell variable. This would cause the test to hang at a host key prompt if you have an A or CNAME for "proxy" in your local domain. Upstream-Regress-ID: 6ea03bcd39443a83c89e2c5606392ceb9585836a commit ed08510d38aef930a061ae30d10f2a9cf233bafa Author: djm@openbsd.org Date: Thu Oct 29 08:05:01 2015 +0000 upstream commit Fix "PubkeyAcceptedKeyTypes +..." inside a Match block; ok dtucker@ Upstream-ID: 853662c4036730b966aab77684390c47b9738c69 commit a4aef3ed29071719b2af82fdf1ac3c2514f82bc5 Author: djm@openbsd.org Date: Tue Oct 27 08:54:52 2015 +0000 upstream commit fix execv arguments in a way less likely to cause grief for -portable; ok dtucker@ Upstream-ID: 5902bf0ea0371f39f1300698dc3b8e4105fc0fc5 commit 63d188175accea83305e89fafa011136ff3d96ad Author: djm@openbsd.org Date: Tue Oct 27 01:44:45 2015 +0000 upstream commit log certificate serial in verbose() messages to match the main auth success/fail message; ok dtucker@ Upstream-ID: dfc48b417c320b97c36ff351d303c142f2186288 commit 2aaba0cfd560ecfe92aa50c00750e6143842cf1f Author: djm@openbsd.org Date: Tue Oct 27 00:49:53 2015 +0000 upstream commit avoid de-const warning & shrink; ok dtucker@ Upstream-ID: 69a85ef94832378952a22c172009cbf52aaa11db commit 03239c18312b9bab7d1c3b03062c61e8bbc1ca6e Author: dtucker@openbsd.org Date: Sun Oct 25 23:42:00 2015 +0000 upstream commit Expand tildes in filenames passed to -i before checking whether or not the identity file exists. This means that if the shell doesn't do the expansion (eg because the option and filename were given as a single argument) then we'll still add the key. bz#2481, ok markus@ Upstream-ID: db1757178a14ac519e9a3e1a2dbd21113cb3bfc6 commit 97e184e508dd33c37860c732c0eca3fc57698b40 Author: dtucker@openbsd.org Date: Sun Oct 25 23:14:03 2015 +0000 upstream commit Do not prepend "exec" to the shell command run by "Match exec" in a config file. It's an unnecessary optimization from repurposed ProxyCommand code and prevents some things working with some shells. bz#2471, pointed out by res at qoxp.net. ok markus@ Upstream-ID: a1ead25ae336bfa15fb58d8c6b5589f85b4c33a3 commit 8db134e7f457bcb069ec72bc4ee722e2af557c69 Author: Darren Tucker Date: Thu Oct 29 10:48:23 2015 +1100 Prevent name collisions with system glob (bz#2463) Move glob.h from includes.h to the only caller (sftp) and override the names for the symbols. This prevents name collisions with the system glob in the case where something other than ssh uses it (eg kerberos). With jjelen at redhat.com, ok djm@ commit 86c10dbbef6a5800d2431a66cf7f41a954bb62b5 Author: dtucker@openbsd.org Date: Fri Oct 23 02:22:01 2015 +0000 upstream commit Update expected group sizes to match recent code changes. Upstream-Regress-ID: 0004f0ea93428969fe75bcfff0d521c553977794 commit 9ada37d36003a77902e90a3214981e417457cf13 Author: djm@openbsd.org Date: Sat Oct 24 22:56:19 2015 +0000 upstream commit fix keyscan output for multiple hosts/addrs on one line when host hashing or a non standard port is in use; bz#2479 ok dtucker@ Upstream-ID: 5321dabfaeceba343da3c8a8b5754c6f4a0a307b commit 44fc7cd7dcef6c52c6b7e9ff830dfa32879bd319 Author: djm@openbsd.org Date: Sat Oct 24 22:52:22 2015 +0000 upstream commit skip "Could not chdir to home directory" message when chrooted patch from Christian Hesse in bz#2485 ok dtucker@ Upstream-ID: 86783c1953da426dff5b03b03ce46e699d9e5431 commit a820a8618ec44735dabc688fab96fba38ad66bb2 Author: sthen@openbsd.org Date: Sat Oct 24 08:34:09 2015 +0000 upstream commit Handle the split of tun(4) "link0" into tap(4) in ssh tun-forwarding. Adapted from portable (using separate devices for this is the normal case in most OS). ok djm@ Upstream-ID: 90facf4c59ce73d6741db1bc926e578ef465cd39 commit 66d2e229baa9fe57b868c373b05f7ff3bb20055b Author: gsoares@openbsd.org Date: Wed Oct 21 11:33:03 2015 +0000 upstream commit fix memory leak in error path ok djm@ Upstream-ID: dd2f402b0a0029b755df029fc7f0679e1365ce35 commit 7d6c0362039ceacdc1366b5df29ad5d2693c13e5 Author: mmcc@openbsd.org Date: Tue Oct 20 23:24:25 2015 +0000 upstream commit Compare pointers to NULL rather than 0. ok djm@ Upstream-ID: 21616cfea27eda65a06e772cc887530b9a1a27f8 commit f98a09cacff7baad8748c9aa217afd155a4d493f Author: mmcc@openbsd.org Date: Tue Oct 20 03:36:35 2015 +0000 upstream commit Replace a function-local allocation with stack memory. ok djm@ Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e commit ac908c1eeacccfa85659594d92428659320fd57e Author: Damien Miller Date: Thu Oct 22 09:35:24 2015 +1100 turn off PrintLastLog when --disable-lastlog bz#2278 from Brent Paulson commit b56deb847f4a0115a8bf488bf6ee8524658162fd Author: djm@openbsd.org Date: Fri Oct 16 22:32:22 2015 +0000 upstream commit increase the minimum modulus that we will send or accept in diffie-hellman-group-exchange to 2048 bits; ok markus@ Upstream-ID: 06dce7a24c17b999a0f5fadfe95de1ed6a1a9b6a commit 5ee0063f024bf5b3f3ffb275b8cd20055d62b4b9 Author: djm@openbsd.org Date: Fri Oct 16 18:40:49 2015 +0000 upstream commit better handle anchored FQDNs (e.g. 'cvs.openbsd.org.') in hostname canonicalisation - treat them as already canonical and remove the trailing '.' before matching ssh_config; ok markus@ Upstream-ID: f7619652e074ac3febe8363f19622aa4853b679a commit e92c499a75477ecfe94dd7b4aed89f20b1fac5a7 Author: mmcc@openbsd.org Date: Fri Oct 16 17:07:24 2015 +0000 upstream commit 0 -> NULL when comparing with a char*. ok dtucker@, djm@. Upstream-ID: a928e9c21c0a9020727d99738ff64027c1272300 commit b1d38a3cc6fe349feb8d16a5f520ef12d1de7cb2 Author: djm@openbsd.org Date: Thu Oct 15 23:51:40 2015 +0000 upstream commit fix some signed/unsigned integer type mismatches in format strings; reported by Nicholas Lemonias Upstream-ID: 78cd55420a0eef68c4095bdfddd1af84afe5f95c commit 1a2663a15d356bb188196b6414b4c50dc12fd42b Author: djm@openbsd.org Date: Thu Oct 15 23:08:23 2015 +0000 upstream commit argument to sshkey_from_private() and sshkey_demote() can't be NULL Upstream-ID: 0111245b1641d387977a9b38da15916820a5fd1f commit 0f754e29dd3760fc0b172c1220f18b753fb0957e Author: Damien Miller Date: Fri Oct 16 10:53:14 2015 +1100 need va_copy before va_start reported by Nicholas Lemonias commit eb6c50d82aa1f0d3fc95f5630ea69761e918bfcd Author: Damien Miller Date: Thu Oct 15 15:48:28 2015 -0700 fix compilation on systems without SYMLOOP_MAX commit fafe1d84a210fb3dae7744f268059cc583db8c12 Author: Damien Miller Date: Wed Oct 14 09:22:15 2015 -0700 s/SANDBOX_TAME/SANDBOX_PLEDGE/g commit 8f22911027ff6c17d7226d232ccd20727f389310 Author: Damien Miller Date: Wed Oct 14 08:28:19 2015 +1100 upstream commit revision 1.20 date: 2015/10/13 20:55:37; author: millert; state: Exp; lines: +2 -2; commitid: X39sl5ay1czgFIgp; In rev 1.15 the sizeof argument was fixed in a strlcat() call but the truncation check immediately following it was not updated to match. Not an issue in practice since the buffers are the same size. OK deraadt@ commit 23fa695bb735f54f04d46123662609edb6c76767 Author: Damien Miller Date: Wed Oct 14 08:27:51 2015 +1100 upstream commit revision 1.19 date: 2015/01/16 16:48:51; author: deraadt; state: Exp; lines: +3 -3; commitid: 0DYulI8hhujBHMcR; Move to the universe. review by millert, binary checking process with doug, concept with guenther commit c71be375a69af00c2d0a0c24d8752bec12d8fd1b Author: Damien Miller Date: Wed Oct 14 08:27:08 2015 +1100 upstream commit revision 1.18 date: 2014/10/19 03:56:28; author: doug; state: Exp; lines: +9 -9; commitid: U6QxmtbXrGoc02S5; Revert last commit due to changed semantics found by make release. commit c39ad23b06e9aecc3ff788e92f787a08472905b1 Author: Damien Miller Date: Wed Oct 14 08:26:24 2015 +1100 upstream commit revision 1.17 date: 2014/10/18 20:43:52; author: doug; state: Exp; lines: +10 -10; commitid: I74hI1tVZtsspKEt; Better POSIX compliance in realpath(3). millert@ made changes to realpath.c based on FreeBSD's version. I merged Todd's changes into dl_realpath.c. ok millert@, guenther@ commit e929a43f957dbd1254aca2aaf85c8c00cbfc25f4 Author: Damien Miller Date: Wed Oct 14 08:25:55 2015 +1100 upstream commit revision 1.16 date: 2013/04/05 12:59:54; author: kurt; state: Exp; lines: +3 -1; - Add comments regarding copies of these files also in libexec/ld.so okay guenther@ commit 5225db68e58a1048cb17f0e36e0d33bc4a8fc410 Author: Damien Miller Date: Wed Oct 14 08:25:32 2015 +1100 upstream commit revision 1.15 date: 2012/09/13 15:39:05; author: deraadt; state: Exp; lines: +2 -2; specify the bounds of the dst to strlcat (both values were static and equal, but it is more correct) from Michal Mazurek commit 7365fe5b4859de2305e40ea132da3823830fa710 Author: Damien Miller Date: Wed Oct 14 08:25:09 2015 +1100 upstream commit revision 1.14 date: 2011/07/24 21:03:00; author: miod; state: Exp; lines: +35 -13; Recent Single Unix will malloc memory if the second argument of realpath() is NULL, and third-party software is starting to rely upon this. Adapted from FreeBSD via Jona Joachim (jaj ; hcl-club , .lu), with minor tweaks from nicm@ and yours truly. commit e679c09cd1951f963793aa3d9748d1c3fdcf808f Author: djm@openbsd.org Date: Tue Oct 13 16:15:21 2015 +0000 upstream commit apply PubkeyAcceptedKeyTypes filtering earlier, so all skipped keys are noted before pubkey authentication starts. ok dtucker@ Upstream-ID: ba4f52f54268a421a2a5f98bb375403f4cb044b8 commit 179c353f564ec7ada64b87730b25fb41107babd7 Author: djm@openbsd.org Date: Tue Oct 13 00:21:27 2015 +0000 upstream commit free the correct IV length, don't assume it's always the cipher blocksize; ok dtucker@ Upstream-ID: c260d9e5ec73628d9ff4b067fbb060eff5a7d298 commit 2539dce2a049a8f6bb0d44cac51f07ad48e691d3 Author: deraadt@openbsd.org Date: Fri Oct 9 01:37:08 2015 +0000 upstream commit Change all tame callers to namechange to pledge(2). Upstream-ID: 17e654fc27ceaf523c60f4ffd9ec7ae4e7efc7f2 commit 9846a2f4067383bb76b4e31a9d2303e0a9c13a73 Author: Damien Miller Date: Thu Oct 8 04:30:48 2015 +1100 hook tame(2) sandbox up to build OpenBSD only for now commit 0c46bbe68b70bdf0d6d20588e5847e71f3739fe6 Author: djm@openbsd.org Date: Wed Oct 7 15:59:12 2015 +0000 upstream commit include PubkeyAcceptedKeyTypes in ssh -G config dump Upstream-ID: 6c097ce6ffebf6fe393fb7988b5d152a5d6b36bb commit bdcb73fb7641b1cf73c0065d1a0dd57b1e8b778e Author: sobrado@openbsd.org Date: Wed Oct 7 14:45:30 2015 +0000 upstream commit UsePrivilegeSeparation defaults to sandbox now. ok djm@ Upstream-ID: bff136c38bcae89df82e044d2f42de21e1ad914f commit 2905d6f99c837bb699b6ebc61711b19acd030709 Author: djm@openbsd.org Date: Wed Oct 7 00:54:06 2015 +0000 upstream commit don't try to change tun device flags if they are already what we need; makes it possible to use tun/tap networking as non- root user if device permissions and interface flags are pre-established; based on patch by Ossi Herrala Upstream-ID: 89099ac4634cd477b066865acf54cb230780fd21 commit 0dc74512bdb105b048883f07de538b37e5e024d4 Author: Damien Miller Date: Mon Oct 5 18:33:05 2015 -0700 unbreak merge botch commit fdd020e86439afa7f537e2429d29d4b744c94331 Author: djm@openbsd.org Date: Tue Oct 6 01:20:59 2015 +0000 upstream commit adapt to recent sshkey_parse_private_fileblob() API change Upstream-Regress-ID: 5c0d818da511e33e0abf6a92a31bd7163b7ad988 commit 21ae8ee3b630b0925f973db647a1b9aa5fcdd4c5 Author: djm@openbsd.org Date: Thu Sep 24 07:15:39 2015 +0000 upstream commit fix command-line option to match what was actually committed Upstream-Regress-ID: 3e8c24a2044e8afd37e7ce17b69002ca817ac699 commit e14ac43b75e68f1ffbd3e1a5e44143c8ae578dcd Author: djm@openbsd.org Date: Thu Sep 24 06:16:53 2015 +0000 upstream commit regress test for CertificateFile; patch from Meghana Bhat via bz#2436 Upstream-Regress-ID: e7a6e980cbe0f8081ba2e83de40d06c17be8bd25 commit 905b054ed24e0d5b4ef226ebf2c8bfc02ae6d4ad Author: djm@openbsd.org Date: Mon Oct 5 17:11:21 2015 +0000 upstream commit some more bzero->explicit_bzero, from Michael McConville Upstream-ID: 17f19545685c33327db2efdc357c1c9225ff00d0 commit b007159a0acdbcf65814b3ee05dbe2cf4ea46011 Author: deraadt@openbsd.org Date: Fri Oct 2 15:52:55 2015 +0000 upstream commit fix email Upstream-ID: 72150f2d54b94de14ebef1ea054ef974281bf834 commit b19e1b4ab11884c4f62aee9f8ab53127a4732658 Author: deraadt@openbsd.org Date: Fri Oct 2 01:39:52 2015 +0000 upstream commit a sandbox using tame ok djm Upstream-ID: 4ca24e47895e72f5daaa02f3e3d3e5ca2d820fa3 commit c61b42f2678f21f05653ac2d3d241b48ab5d59ac Author: deraadt@openbsd.org Date: Fri Oct 2 01:39:26 2015 +0000 upstream commit re-order system calls in order of risk, ok i'll be honest, ordered this way they look like tame... ok djm Upstream-ID: 42a1e6d251fd8be13c8262bee026059ae6328813 commit c5f7c0843cb6e6074a93c8ac34e49ce33a6f5546 Author: jmc@openbsd.org Date: Fri Sep 25 18:19:54 2015 +0000 upstream commit some certificatefile tweaks; ok djm Upstream-ID: 0e5a7852c28c05fc193419cc7e50e64c1c535af0 commit 4e44a79a07d4b88b6a4e5e8c1bed5f58c841b1b8 Author: djm@openbsd.org Date: Thu Sep 24 06:15:11 2015 +0000 upstream commit add ssh_config CertificateFile option to explicitly list a certificate; patch from Meghana Bhat on bz#2436; ok markus@ Upstream-ID: 58648ec53c510b41c1f46d8fe293aadc87229ab8 commit e3cbb06ade83c72b640a53728d362bbefa0008e2 Author: sobrado@openbsd.org Date: Tue Sep 22 08:33:23 2015 +0000 upstream commit fix two typos. Upstream-ID: 424402c0d8863a11b51749bacd7f8d932083b709 commit 8408218c1ca88cb17d15278174a24a94a6f65fe1 Author: djm@openbsd.org Date: Mon Sep 21 04:31:00 2015 +0000 upstream commit fix possible hang on closed output; bz#2469 reported by Tomas Kuthan ok markus@ Upstream-ID: f7afd41810f8540f524284f1be6b970859f94fe3 commit 0097248f90a00865082e8c146b905a6555cc146f Author: djm@openbsd.org Date: Fri Sep 11 04:55:01 2015 +0000 upstream commit skip if running as root; many systems (inc OpenBSD) allow root to ptrace arbitrary processes Upstream-Regress-ID: be2b925df89360dff36f972951fa0fa793769038 commit 9c06c814aff925e11a5cc592c06929c258a014f6 Author: djm@openbsd.org Date: Fri Sep 11 03:44:21 2015 +0000 upstream commit try all supported key types here; bz#2455 reported by Jakub Jelen Upstream-Regress-ID: 188cb7d9031cdbac3a0fa58b428b8fa2b2482bba commit 3c019a936b43f3e2773f3edbde7c114d73caaa4c Author: tim@openbsd.org Date: Sun Sep 13 14:39:16 2015 +0000 upstream commit - Fix error message: passphrase needs to be at least 5 characters, not 4. - Remove unused function argument. - Remove two unnecessary variables. OK djm@ Upstream-ID: 13010c05bfa8b523da1c0dc19e81dd180662bc30 commit 2681cdb6e0de7c1af549dac37a9531af202b4434 Author: tim@openbsd.org Date: Sun Sep 13 13:48:19 2015 +0000 upstream commit When adding keys to the agent, don't ignore the comment of keys for which the user is prompted for a passphrase. Tweak and OK djm@ Upstream-ID: dc737c620a5a8d282cc4f66e3b9b624e9abefbec commit 14692f7b8251cdda847e648a82735eef8a4d2a33 Author: guenther@openbsd.org Date: Fri Sep 11 08:50:04 2015 +0000 upstream commit Use explicit_bzero() when zeroing before free() from Michael McConville (mmcconv1 (at) sccs.swarthmore.edu) ok millert@ djm@ Upstream-ID: 2e3337db046c3fe70c7369ee31515ac73ec00f50 commit 846f6fa4cfa8483a9195971dbdd162220f199d85 Author: jmc@openbsd.org Date: Fri Sep 11 06:55:46 2015 +0000 upstream commit sync -Q in usage() to SYNOPSIS; since it's drastically shorter, i've reformatted the block to sync with the man (80 cols) and saved a line; Upstream-ID: 86e2c65c3989a0777a6258a77e589b9f6f354abd commit 95923e0520a8647417ee6dcdff44694703dfeef0 Author: jmc@openbsd.org Date: Fri Sep 11 06:51:39 2015 +0000 upstream commit tweak previous; Upstream-ID: f29b3cfcfd9aa31fa140c393e7bd48c1c74139d6 commit 86ac462f833b05d8ed9de9c50ccb295d7faa79ff Author: dtucker@openbsd.org Date: Fri Sep 11 05:27:02 2015 +0000 upstream commit Update usage to match man page. Upstream-ID: 9e85aefaecfb6aaf34c7cfd0700cd21783a35675 commit 674b3b68c1d36b2562324927cd03857b565e05e8 Author: djm@openbsd.org Date: Fri Sep 11 03:47:28 2015 +0000 upstream commit expand %i in ControlPath to UID; bz#2449 patch from Christian Hesse w/ feedback from dtucker@ Upstream-ID: 2ba8d303e555a84e2f2165ab4b324b41e80ab925 commit c0f55db7ee00c8202b05cb4b9ad4ce72cc45df41 Author: djm@openbsd.org Date: Fri Sep 11 03:42:32 2015 +0000 upstream commit mention -Q key-plain and -Q key-cert; bz#2455 pointed out by Jakub Jelen Upstream-ID: c8f1f8169332e4fa73ac96b0043e3b84e01d4896 commit cfffbdb10fdf0f02d3f4232232eef7ec3876c383 Author: Darren Tucker Date: Mon Sep 14 16:24:21 2015 +1000 Use ssh-keygen -A when generating host keys. Use ssh-keygen -A instead of per-keytype invocations when generating host keys. Add tests when doing host-key-force since we can't use ssh-keygen -A since it can't specify alternate locations. bz#2459, ok djm@ commit 366bada1e9e124654aac55b72b6ccf878755b0dc Author: Darren Tucker Date: Fri Sep 11 13:29:22 2015 +1000 Correct default value for --with-ssh1. bz#2457, from konto-mindrot.org at walimnieto.com. commit 2bca8a43e7dd9b04d7070824ffebb823c72587b2 Author: djm@openbsd.org Date: Fri Sep 11 03:13:36 2015 +0000 upstream commit more clarity on what AuthorizedKeysFile=none does; based on diff by Thiebaud Weksteen Upstream-ID: 78ab87f069080f0cc3bc353bb04eddd9e8ad3704 commit 61942ea4a01e6db4fdf37ad61de81312ffe310e9 Author: djm@openbsd.org Date: Wed Sep 9 00:52:44 2015 +0000 upstream commit openssh_RSA_verify return type is int, so don't make it size_t within the function itself with only negative numbers or zero assigned to it. bz#2460 Upstream-ID: b6e794b0c7fc4f9f329509263c8668d35f83ea55 commit 4f7cc2f8cc861a21e6dbd7f6c25652afb38b9b96 Author: dtucker@openbsd.org Date: Fri Sep 4 08:21:47 2015 +0000 upstream commit Plug minor memory leaks when options are used more than once. bz#2182, patch from Tiago Cunha, ok deraadt djm Upstream-ID: 5b84d0401e27fe1614c10997010cc55933adb48e commit 7ad8b287c8453a3e61dbc0d34d467632b8b06fc8 Author: Darren Tucker Date: Fri Sep 11 13:11:02 2015 +1000 Force resolution of _res for correct detection. bz#2259, from sconeu at yahoo.com. commit 26ad18247213ff72b4438abe7fc660c958810fa2 Author: Damien Miller Date: Thu Sep 10 10:57:41 2015 +1000 allow getrandom syscall; from Felix von Leitner commit 5245bc1e6b129a10a928f73f11c3aa32656c44b4 Author: jmc@openbsd.org Date: Fri Sep 4 06:40:45 2015 +0000 upstream commit full stop belongs outside the brackets, not inside; Upstream-ID: 99d098287767799ac33d2442a05b5053fa5a551a commit a85768a9321d74b41219eeb3c9be9f1702cbf6a5 Author: djm@openbsd.org Date: Fri Sep 4 04:56:09 2015 +0000 upstream commit add a debug2() right before DNS resolution; it's a place where ssh could previously silently hang for a while. bz#2433 Upstream-ID: 52a1a3e0748db66518e7598352c427145692a6a0 commit 46152af8d27aa34d5d26ed1c371dc8aa142d4730 Author: djm@openbsd.org Date: Fri Sep 4 04:55:24 2015 +0000 upstream commit correct function name in error messages Upstream-ID: 92fb2798617ad9561370897f4ab60adef2ff4c0e commit a954cdb799a4d83c2d40fbf3e7b9f187fbfd72fc Author: djm@openbsd.org Date: Fri Sep 4 04:47:50 2015 +0000 upstream commit better document ExitOnForwardFailure; bz#2444, ok dtucker@ Upstream-ID: a126209b5a6d9cb3117ac7ab5bc63d284538bfc2 commit f54d8ac2474b6fc3afa081cf759b48a6c89d3319 Author: djm@openbsd.org Date: Fri Sep 4 04:44:08 2015 +0000 upstream commit don't record hostbased authentication hostkeys as user keys in test for multiple authentication with the same key Upstream-ID: 26b368fa2cff481f47f37e01b8da1ae5b57b1adc commit ac3451dd65f27ecf85dc045c46d49e2bbcb8dddd Author: djm@openbsd.org Date: Fri Sep 4 03:57:38 2015 +0000 upstream commit remove extra newline in nethack-mode hostkey; from Christian Hesse bz#2686 Upstream-ID: 4f56368b1cc47baeea0531912186f66007fd5b92 commit 9e3ed9ebb1a7e47c155c28399ddf09b306ea05df Author: djm@openbsd.org Date: Fri Sep 4 04:23:10 2015 +0000 upstream commit trim junk from end of file; bz#2455 from Jakub Jelen Upstream-Regress-ID: a4e64e8931e40d23874b047074444eff919cdfe6 commit f3a3ea180afff080bab82087ee0b60db9fd84f6c Author: jsg@openbsd.org Date: Wed Sep 2 07:51:12 2015 +0000 upstream commit Fix occurrences of "r = func() != 0" which result in the wrong error codes being returned due to != having higher precedence than =. ok deraadt@ markus@ Upstream-ID: 5fc35c9fc0319cc6fca243632662d2f06b5fd840 commit f498a98cf83feeb7ea01c15cd1c98b3111361f3a Author: Damien Miller Date: Thu Sep 3 09:11:22 2015 +1000 don't check for yp_match; ok tim@ commit 9690b78b7848b0b376980a61d51b1613e187ddb5 Author: djm@openbsd.org Date: Fri Aug 21 23:57:48 2015 +0000 upstream commit Improve printing of KEX offers and decisions The debug output now labels the client and server offers and the negotiated options. ok markus@ Upstream-ID: 8db921b3f92a4565271b1c1fbce6e7f508e1a2cb commit 60a92470e21340e1a3fc10f9c7140d8e1519dc55 Author: djm@openbsd.org Date: Fri Aug 21 23:53:08 2015 +0000 upstream commit Fix printing (ssh -G ...) of HostKeyAlgorithms=+... Reported by Bryan Drewery Upstream-ID: 19ad20c41bd5971e006289b6f9af829dd46c1293 commit 6310f60fffca2d1e464168e7d1f7e3b6b0268897 Author: djm@openbsd.org Date: Fri Aug 21 23:52:30 2015 +0000 upstream commit Fix expansion of HostkeyAlgorithms=+... Reported by Bryan Drewery Upstream-ID: 70ca1deea39d758ba36d36428ae832e28566f78d commit e774e5ea56237fd626a8161f9005023dff3e76c9 Author: deraadt@openbsd.org Date: Fri Aug 21 23:29:31 2015 +0000 upstream commit Improve size == 0, count == 0 checking in mm_zalloc, which is "array" like. Discussed with tedu, millert, otto.... and ok djm Upstream-ID: 899b021be43b913fad3eca1aef44efe710c53e29 commit 189de02d9ad6f3645417c0ddf359b923aae5f926 Author: Damien Miller Date: Fri Aug 21 15:45:02 2015 +1000 expose POLLHUP and POLLNVAL for netcat.c commit e91346dc2bbf460246df2ab591b7613908c1b0ad Author: Damien Miller Date: Fri Aug 21 14:49:03 2015 +1000 we don't use Github for issues/pull-requests commit a4f5b507c708cc3dc2c8dd2d02e4416d7514dc23 Author: Damien Miller Date: Fri Aug 21 14:43:55 2015 +1000 fix URL for connect.c commit d026a8d3da0f8186598442997c7d0a28e7275414 Author: Damien Miller Date: Fri Aug 21 13:47:10 2015 +1000 update version numbers for 7.1 commit 78f8f589f0ca1c9f41e5a9bae3cda5ce8a6b42ed Author: djm@openbsd.org Date: Fri Aug 21 03:45:26 2015 +0000 upstream commit openssh-7.1 Upstream-ID: ff7b1ef4b06caddfb45e08ba998128c88be3d73f commit 32a181980c62fce94f7f9ffaf6a79d90f0c309cf Author: djm@openbsd.org Date: Fri Aug 21 03:42:19 2015 +0000 upstream commit fix inverted logic that broke PermitRootLogin; reported by Mantas Mikulenas; ok markus@ Upstream-ID: 260dd6a904c1bb7e43267e394b1c9cf70bdd5ea5 commit ce445b0ed927e45bd5bdce8f836eb353998dd65c Author: deraadt@openbsd.org Date: Thu Aug 20 22:32:42 2015 +0000 upstream commit Do not cast result of malloc/calloc/realloc* if stdlib.h is in scope ok krw millert Upstream-ID: 5e50ded78cadf3841556649a16cc4b1cb6c58667 commit 05291e5288704d1a98bacda269eb5a0153599146 Author: naddy@openbsd.org Date: Thu Aug 20 19:20:06 2015 +0000 upstream commit In the certificates section, be consistent about using "host_key" and "user_key" for the respective key types. ok sthen@ deraadt@ Upstream-ID: 9e037ea3b15577b238604c5533e082a3947f13cb commit 8543d4ef6f2e9f98c3e6b77c894ceec30c5e4ae4 Author: djm@openbsd.org Date: Wed Aug 19 23:21:42 2015 +0000 upstream commit Better compat matching for WinSCP, add compat matching for FuTTY (fork of PuTTY); ok markus@ deraadt@ Upstream-ID: 24001d1ac115fa3260fbdc329a4b9aeb283c5389 commit ec6eda16ebab771aa3dfc90629b41953b999cb1e Author: djm@openbsd.org Date: Wed Aug 19 23:19:01 2015 +0000 upstream commit fix double-free() in error path of DSA key generation reported by Mateusz Kocielski; ok markus@ Upstream-ID: 4735d8f888b10599a935fa1b374787089116713c commit 45b0eb752c94954a6de046bfaaf129e518ad4b5b Author: djm@openbsd.org Date: Wed Aug 19 23:18:26 2015 +0000 upstream commit fix free() of uninitialised pointer reported by Mateusz Kocielski; ok markus@ Upstream-ID: 519552b050618501a06b7b023de5cb104e2c5663 commit c837643b93509a3ef538cb6624b678c5fe32ff79 Author: djm@openbsd.org Date: Wed Aug 19 23:17:51 2015 +0000 upstream commit fixed unlink([uninitialised memory]) reported by Mateusz Kocielski; ok markus@ Upstream-ID: 14a0c4e7d891f5a8dabc4b89d4f6b7c0d5a20109 commit 1f8d3d629cd553031021068eb9c646a5f1e50994 Author: jmc@openbsd.org Date: Fri Aug 14 15:32:41 2015 +0000 upstream commit match myproposal.h order; from brian conway (i snuck in a tweak while here) ok dtucker Upstream-ID: 35174a19b5237ea36aa3798f042bf5933b772c67 commit 1dc8d93ce69d6565747eb44446ed117187621b26 Author: deraadt@openbsd.org Date: Thu Aug 6 14:53:21 2015 +0000 upstream commit add prohibit-password as a synonymn for without-password, since the without-password is causing too many questions. Harden it to ban all but pubkey, hostbased, and GSSAPI auth (when the latter is enabled) from djm, ok markus Upstream-ID: d53317d7b28942153e6236d3fd6e12ceb482db7a commit 90a95a4745a531b62b81ce3b025e892bdc434de5 Author: Damien Miller Date: Tue Aug 11 13:53:41 2015 +1000 update version in README commit 318c37743534b58124f1bab37a8a0087a3a9bd2f Author: Damien Miller Date: Tue Aug 11 13:53:09 2015 +1000 update versions in *.spec commit 5e75f5198769056089fb06c4d738ab0e5abc66f7 Author: Damien Miller Date: Tue Aug 11 13:34:12 2015 +1000 set sshpam_ctxt to NULL after free Avoids use-after-free in monitor when privsep child is compromised. Reported by Moritz Jodeit; ok dtucker@ commit d4697fe9a28dab7255c60433e4dd23cf7fce8a8b Author: Damien Miller Date: Tue Aug 11 13:33:24 2015 +1000 Don't resend username to PAM; it already has it. Pointed out by Moritz Jodeit; ok dtucker@ commit 88763a6c893bf3dfe951ba9271bf09715e8d91ca Author: Darren Tucker Date: Mon Jul 27 12:14:25 2015 +1000 Import updated moduli file from OpenBSD. commit 55b263fb7cfeacb81aaf1c2036e0394c881637da Author: Damien Miller Date: Mon Aug 10 11:13:44 2015 +1000 let principals-command.sh work for noexec /var/run commit 2651e34cd11b1aac3a0fe23b86d8c2ff35c07897 Author: Damien Miller Date: Thu Aug 6 11:43:42 2015 +1000 work around echo -n / sed behaviour in tests commit d85dad81778c1aa8106acd46930b25fdf0d15b2a Author: djm@openbsd.org Date: Wed Aug 5 05:27:33 2015 +0000 upstream commit adjust for RSA minimum modulus switch; ok deraadt@ Upstream-Regress-ID: 5a72c83431b96224d583c573ca281cd3a3ebfdae commit 57e8e229bad5fe6056b5f1199665f5f7008192c6 Author: djm@openbsd.org Date: Tue Aug 4 05:23:06 2015 +0000 upstream commit backout SSH_RSA_MINIMUM_MODULUS_SIZE increase for this release; problems spotted by sthen@ ok deraadt@ markus@ Upstream-ID: d0bd60dde9e8c3cd7030007680371894c1499822 commit f097d0ea1e0889ca0fa2e53a00214e43ab7fa22a Author: djm@openbsd.org Date: Sun Aug 2 09:56:42 2015 +0000 upstream commit openssh 7.0; ok deraadt@ Upstream-ID: c63afdef537f57f28ae84145c5a8e29e9250221f commit 3d5728a0f6874ce4efb16913a12963595070f3a9 Author: chris@openbsd.org Date: Fri Jul 31 15:38:09 2015 +0000 upstream commit Allow PermitRootLogin to be overridden by config ok markus@ deeradt@ Upstream-ID: 5cf3e26ed702888de84e2dc9d0054ccf4d9125b4 commit 6f941396b6835ad18018845f515b0c4fe20be21a Author: djm@openbsd.org Date: Thu Jul 30 23:09:15 2015 +0000 upstream commit fix pty permissions; patch from Nikolay Edigaryev; ok deraadt Upstream-ID: 40ff076d2878b916fbfd8e4f45dbe5bec019e550 commit f4373ed1e8fbc7c8ce3fc4ea97d0ba2e0c1d7ef0 Author: deraadt@openbsd.org Date: Thu Jul 30 19:23:02 2015 +0000 upstream commit change default: PermitRootLogin without-password matching install script changes coming as well ok djm markus Upstream-ID: 0e2a6c4441daf5498b47a61767382bead5eb8ea6 commit 0c30ba91f87fcda7e975e6ff8a057f624e87ea1c Author: Damien Miller Date: Thu Jul 30 12:31:39 2015 +1000 downgrade OOM adjustment logging: verbose -> debug commit f9eca249d4961f28ae4b09186d7dc91de74b5895 Author: djm@openbsd.org Date: Thu Jul 30 00:01:34 2015 +0000 upstream commit Allow ssh_config and sshd_config kex parameters options be prefixed by a '+' to indicate that the specified items be appended to the default rather than replacing it. approach suggested by dtucker@, feedback dlg@, ok markus@ Upstream-ID: 0f901137298fc17095d5756ff1561a7028e8882a commit 5cefe769105a2a2e3ca7479d28d9a325d5ef0163 Author: djm@openbsd.org Date: Wed Jul 29 08:34:54 2015 +0000 upstream commit fix bug in previous; was printing incorrect string for failed host key algorithms negotiation Upstream-ID: 22c0dc6bc61930513065d92e11f0753adc4c6e6e commit f319912b0d0e1675b8bb051ed8213792c788bcb2 Author: djm@openbsd.org Date: Wed Jul 29 04:43:06 2015 +0000 upstream commit include the peer's offer when logging a failure to negotiate a mutual set of algorithms (kex, pubkey, ciphers, etc.) ok markus@ Upstream-ID: bbb8caabf5c01790bb845f5ce135565248d7c796 commit b6ea0e573042eb85d84defb19227c89eb74cf05a Author: djm@openbsd.org Date: Tue Jul 28 23:20:42 2015 +0000 upstream commit add Cisco to the list of clients that choke on the hostkeys update extension. Pointed out by Howard Kash Upstream-ID: c9eadde28ecec056c73d09ee10ba4570dfba7e84 commit 3f628c7b537291c1019ce86af90756fb4e66d0fd Author: guenther@openbsd.org Date: Mon Jul 27 16:29:23 2015 +0000 upstream commit Permit kbind(2) use in the sandbox now, to ease testing of ld.so work using it reminded by miod@, ok deraadt@ Upstream-ID: 523922e4d1ba7a091e3824e77a8a3c818ee97413 commit ebe27ebe520098bbc0fe58945a87ce8490121edb Author: millert@openbsd.org Date: Mon Jul 20 18:44:12 2015 +0000 upstream commit Move .Pp before .Bl, not after to quiet mandoc -Tlint. Noticed by jmc@ Upstream-ID: 59fadbf8407cec4e6931e50c53cfa0214a848e23 commit d5d91d0da819611167782c66ab629159169d94d4 Author: millert@openbsd.org Date: Mon Jul 20 18:42:35 2015 +0000 upstream commit Sync usage with SYNOPSIS Upstream-ID: 7a321a170181a54f6450deabaccb6ef60cf3f0b7 commit 79ec2142fbc68dd2ed9688608da355fc0b1ed743 Author: millert@openbsd.org Date: Mon Jul 20 15:39:52 2015 +0000 upstream commit Better desciption of Unix domain socket forwarding. bz#2423; ok jmc@ Upstream-ID: 85e28874726897e3f26ae50dfa2e8d2de683805d commit d56fd1828074a4031b18b8faa0bf949669eb18a0 Author: Damien Miller Date: Mon Jul 20 11:19:51 2015 +1000 make realpath.c compile -Wsign-compare clean commit c63c9a691dca26bb7648827f5a13668832948929 Author: djm@openbsd.org Date: Mon Jul 20 00:30:01 2015 +0000 upstream commit mention that the default of UseDNS=no implies that hostnames cannot be used for host matching in sshd_config and authorized_keys; bz#2045, ok dtucker@ Upstream-ID: 0812705d5f2dfa59aab01f2764ee800b1741c4e1 commit 63ebcd0005e9894fcd6871b7b80aeea1fec0ff76 Author: djm@openbsd.org Date: Sat Jul 18 08:02:17 2015 +0000 upstream commit don't ignore PKCS#11 hosted keys that return empty CKA_ID; patch by Jakub Jelen via bz#2429; ok markus Upstream-ID: 2f7c94744eb0342f8ee8bf97b2351d4e00116485 commit b15fd989c8c62074397160147a8d5bc34b3f3c63 Author: djm@openbsd.org Date: Sat Jul 18 08:00:21 2015 +0000 upstream commit skip uninitialised PKCS#11 slots; patch from Jakub Jelen in bz#2427 ok markus@ Upstream-ID: 744c1e7796e237ad32992d0d02148e8a18f27d29 commit 5b64f85bb811246c59ebab70aed331f26ba37b18 Author: djm@openbsd.org Date: Sat Jul 18 07:57:14 2015 +0000 upstream commit only query each keyboard-interactive device once per authentication request regardless of how many times it is listed; ok markus@ Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1 commit cd7324d0667794eb5c236d8a4e0f236251babc2d Author: djm@openbsd.org Date: Fri Jul 17 03:34:27 2015 +0000 upstream commit remove -u flag to diff (only used for error output) to make things easier for -portable Upstream-Regress-ID: a5d6777d2909540d87afec3039d9bb2414ade548 commit deb8d99ecba70b67f4af7880b11ca8768df9ec3a Author: djm@openbsd.org Date: Fri Jul 17 03:09:19 2015 +0000 upstream commit direct-streamlocal@openssh.com Unix domain foward messages do not contain a "reserved for future use" field and in fact, serverloop.c checks that there isn't one. Remove erroneous mention from PROTOCOL description. bz#2421 from Daniel Black Upstream-ID: 3d51a19e64f72f764682f1b08f35a8aa810a43ac commit 356b61f365405b5257f5b2ab446e5d7bd33a7b52 Author: djm@openbsd.org Date: Fri Jul 17 03:04:27 2015 +0000 upstream commit describe magic for setting up Unix domain socket fowards via the mux channel; bz#2422 patch from Daniel Black Upstream-ID: 943080fe3864715c423bdeb7c920bb30c4eee861 commit d3e2aee41487d55b8d7d40f538b84ff1db7989bc Author: Darren Tucker Date: Fri Jul 17 12:52:34 2015 +1000 Check if realpath works on nonexistent files. On some platforms the native realpath doesn't work with non-existent files (this is actually specified in some versions of POSIX), however the sftp spec says its realpath with "canonicalize any given path name". On those platforms, use realpath from the compat library. In addition, when compiling with -DFORTIFY_SOURCE, glibc redefines the realpath symbol to the checked version, so redefine ours to something else so we pick up the compat version we want. bz#2428, ok djm@ commit 25b14610dab655646a109db5ef8cb4c4bf2a48a0 Author: djm@openbsd.org Date: Fri Jul 17 02:47:45 2015 +0000 upstream commit fix incorrect test for SSH1 keys when compiled without SSH1 support Upstream-ID: 6004d720345b8e481c405e8ad05ce2271726e451 commit df56a8035d429b2184ee94aaa7e580c1ff67f73a Author: djm@openbsd.org Date: Wed Jul 15 08:00:11 2015 +0000 upstream commit fix NULL-deref when SSH1 reenabled Upstream-ID: f22fd805288c92b3e9646782d15b48894b2d5295 commit 41e38c4d49dd60908484e6703316651333f16b93 Author: djm@openbsd.org Date: Wed Jul 15 07:19:50 2015 +0000 upstream commit regen RSA1 test keys; the last batch was missing their private parts Upstream-Regress-ID: 7ccf437305dd63ff0b48dd50c5fd0f4d4230c10a commit 5bf0933184cb622ca3f96d224bf3299fd2285acc Author: markus@openbsd.org Date: Fri Jul 10 06:23:25 2015 +0000 upstream commit Adapt tests, now that DSA if off by default; use PubkeyAcceptedKeyTypes and PubkeyAcceptedKeyTypes to test DSA. Upstream-Regress-ID: 0ff2a3ff5ac1ce5f92321d27aa07b98656efcc5c commit 7a6e3fd7b41dbd3756b6bf9acd67954c0b1564cc Author: markus@openbsd.org Date: Tue Jul 7 14:54:16 2015 +0000 upstream commit regen test data after mktestdata.sh changes Upstream-Regress-ID: 3495ecb082b9a7c048a2d7c5c845d3bf181d25a4 commit 7c8c174c69f681d4910fa41c37646763692b28e2 Author: markus@openbsd.org Date: Tue Jul 7 14:53:30 2015 +0000 upstream commit adapt tests to new minimum RSA size and default FP format Upstream-Regress-ID: a4b30afd174ce82b96df14eb49fb0b81398ffd0e commit 6a977a4b68747ade189e43d302f33403fd4a47ac Author: djm@openbsd.org Date: Fri Jul 3 04:39:23 2015 +0000 upstream commit legacy v00 certificates are gone; adapt and don't try to test them; "sure" markus@ dtucker@ Upstream-Regress-ID: c57321e69b3cd4a3b3396dfcc43f0803d047da12 commit 0c4123ad5e93fb90fee9c6635b13a6cdabaac385 Author: djm@openbsd.org Date: Wed Jul 1 23:11:18 2015 +0000 upstream commit don't expect SSH v.1 in unittests Upstream-Regress-ID: f8812b16668ba78e6a698646b2a652b90b653397 commit 3c099845798a817cdde513c39074ec2063781f18 Author: djm@openbsd.org Date: Mon Jun 15 06:38:50 2015 +0000 upstream commit turn SSH1 back on to match src/usr.bin/ssh being tested Upstream-Regress-ID: 6c4f763a2f0cc6893bf33983919e9030ae638333 commit b1dc2b33689668c75e95f873a42d5aea1f4af1db Author: dtucker@openbsd.org Date: Mon Jul 13 04:57:14 2015 +0000 upstream commit Add "PuTTY_Local:" to the clients to which we do not offer DH-GEX. This was the string that was used for development versions prior to September 2014 and they don't do RFC4419 DH-GEX, but unfortunately there are some extant products based on those versions. bx2424 from Jay Rouman, ok markus@ djm@ Upstream-ID: be34d41e18b966832fe09ca243d275b81882e1d5 commit 3a1638dda19bbc73d0ae02b4c251ce08e564b4b9 Author: markus@openbsd.org Date: Fri Jul 10 06:21:53 2015 +0000 upstream commit Turn off DSA by default; add HostKeyAlgorithms to the server and PubkeyAcceptedKeyTypes to the client side, so it still can be tested or turned back on; feedback and ok djm@ Upstream-ID: 8450a9e6d83f80c9bfed864ff061dfc9323cec21 commit 16db0a7ee9a87945cc594d13863cfcb86038db59 Author: markus@openbsd.org Date: Thu Jul 9 09:49:46 2015 +0000 upstream commit re-enable ed25519-certs if compiled w/o openssl; ok djm Upstream-ID: e10c90808b001fd2c7a93778418e9b318f5c4c49 commit c355bf306ac33de6545ce9dac22b84a194601e2f Author: markus@openbsd.org Date: Wed Jul 8 20:24:02 2015 +0000 upstream commit no need to include the old buffer/key API Upstream-ID: fb13c9f7c0bba2545f3eb0a0e69cb0030819f52b commit a3cc48cdf9853f1e832d78cb29bedfab7adce1ee Author: markus@openbsd.org Date: Wed Jul 8 19:09:25 2015 +0000 upstream commit typedefs for Cipher&CipherContext are unused Upstream-ID: 50e6a18ee92221d23ad173a96d5b6c42207cf9a7 commit a635bd06b5c427a57c3ae760d3a2730bb2c863c0 Author: markus@openbsd.org Date: Wed Jul 8 19:04:21 2015 +0000 upstream commit xmalloc.h is unused Upstream-ID: afb532355b7fa7135a60d944ca1e644d1d63cb58 commit 2521cf0e36c7f3f6b19f206da0af134f535e4a31 Author: markus@openbsd.org Date: Wed Jul 8 19:01:15 2015 +0000 upstream commit compress.c is gone Upstream-ID: 174fa7faa9b9643cba06164b5e498591356fbced commit c65a7aa6c43aa7a308ee1ab8a96f216169ae9615 Author: djm@openbsd.org Date: Fri Jul 3 04:05:54 2015 +0000 upstream commit another SSH_RSA_MINIMUM_MODULUS_SIZE that needed cranking Upstream-ID: 9d8826cafe96aab4ae8e2f6fd22800874b7ffef1 commit b1f383da5cd3cb921fc7776f17a14f44b8a31757 Author: djm@openbsd.org Date: Fri Jul 3 03:56:25 2015 +0000 upstream commit add an XXX reminder for getting correct key paths from sshd_config Upstream-ID: feae52b209d7782ad742df04a4260e9fe41741db commit 933935ce8d093996c34d7efa4d59113163080680 Author: djm@openbsd.org Date: Fri Jul 3 03:49:45 2015 +0000 upstream commit refuse to generate or accept RSA keys smaller than 1024 bits; feedback and ok dtucker@ Upstream-ID: 7ea3d31271366ba264f06e34a3539bf1ac30f0ba commit bdfd29f60b74f3e678297269dc6247a5699583c1 Author: djm@openbsd.org Date: Fri Jul 3 03:47:00 2015 +0000 upstream commit turn off 1024 bit diffie-hellman-group1-sha1 key exchange method (already off in server, this turns it off in the client by default too) ok dtucker@ Upstream-ID: f59b88f449210ab7acf7d9d88f20f1daee97a4fa commit c28fc62d789d860c75e23a9fa9fb250eb2beca57 Author: djm@openbsd.org Date: Fri Jul 3 03:43:18 2015 +0000 upstream commit delete support for legacy v00 certificates; "sure" markus@ dtucker@ Upstream-ID: b5b9bb5f9202d09e88f912989d74928601b6636f commit 564d63e1b4a9637a209d42a9d49646781fc9caef Author: djm@openbsd.org Date: Wed Jul 1 23:10:47 2015 +0000 upstream commit Compile-time disable SSH v.1 again Upstream-ID: 1d4b513a3a06232f02650b73bad25100d1b800af commit 868109b650504dd9bcccdb1f51d0906f967c20ff Author: djm@openbsd.org Date: Wed Jul 1 02:39:06 2015 +0000 upstream commit twiddle PermitRootLogin back Upstream-ID: 2bd23976305d0512e9f84d054e1fc23cd70b89f2 commit 7de4b03a6e4071d454b72927ffaf52949fa34545 Author: djm@openbsd.org Date: Wed Jul 1 02:32:17 2015 +0000 upstream commit twiddle; (this commit marks the openssh-6.9 release) Upstream-ID: 78500582819f61dd8adee36ec5cc9b9ac9351234 commit 1bf477d3cdf1a864646d59820878783d42357a1d Author: djm@openbsd.org Date: Wed Jul 1 02:26:31 2015 +0000 upstream commit better refuse ForwardX11Trusted=no connections attempted after ForwardX11Timeout expires; reported by Jann Horn Upstream-ID: bf0fddadc1b46a0334e26c080038313b4b6dea21 commit 47aa7a0f8551b471fcae0447c1d78464f6dba869 Author: djm@openbsd.org Date: Wed Jul 1 01:56:13 2015 +0000 upstream commit put back default PermitRootLogin=no Upstream-ID: 7bdedd5cead99c57ed5571f3b6b7840922d5f728 commit 984b064fe2a23733733262f88d2e1b2a1a501662 Author: djm@openbsd.org Date: Wed Jul 1 01:55:13 2015 +0000 upstream commit openssh-6.9 Upstream-ID: 6cfe8e1904812531080e6ab6e752d7001b5b2d45 commit d921082ed670f516652eeba50705e1e9f6325346 Author: djm@openbsd.org Date: Wed Jul 1 01:55:00 2015 +0000 upstream commit reset default PermitRootLogin to 'yes' (momentarily, for release) Upstream-ID: cad8513527066e65dd7a1c16363d6903e8cefa24 commit 66295e0e1ba860e527f191b6325d2d77dec4dbce Author: Damien Miller Date: Wed Jul 1 11:49:12 2015 +1000 crank version numbers for release commit 37035c07d4f26bb1fbe000d2acf78efdb008681d Author: Damien Miller Date: Wed Jul 1 10:49:37 2015 +1000 s/--with-ssh1/--without-ssh1/ commit 629df770dbadc2accfbe1c81b3f31f876d0acd84 Author: djm@openbsd.org Date: Tue Jun 30 05:25:07 2015 +0000 upstream commit fatal() when a remote window update causes the window value to overflow. Reported by Georg Wicherski, ok markus@ Upstream-ID: ead397a9aceb3bf74ebfa5fcaf259d72e569f351 commit f715afebe735d61df3fd30ad72d9ac1c8bd3b5f2 Author: djm@openbsd.org Date: Tue Jun 30 05:23:25 2015 +0000 upstream commit Fix math error in remote window calculations that causes eventual stalls for datagram channels. Reported by Georg Wicherski, ok markus@ Upstream-ID: be54059d11bf64e0d85061f7257f53067842e2ab commit 52fb6b9b034fcfd24bf88cc7be313e9c31de9889 Author: Damien Miller Date: Tue Jun 30 16:05:40 2015 +1000 skip IPv6-related portions on hosts without IPv6 with Tim Rice commit 512caddf590857af6aa12218461b5c0441028cf5 Author: djm@openbsd.org Date: Mon Jun 29 22:35:12 2015 +0000 upstream commit add getpid to sandbox, reachable by grace_alarm_handler reported by Jakub Jelen; bz#2419 Upstream-ID: d0da1117c16d4c223954995d35b0f47c8f684cd8 commit 78c2a4f883ea9aba866358e2acd9793a7f42ca93 Author: djm@openbsd.org Date: Fri Jun 26 05:13:20 2015 +0000 upstream commit Fix \-escaping bug that caused forward path parsing to skip two characters and skip past the end of the string. Based on patch by Salvador Fandino; ok dtucker@ Upstream-ID: 7b879dc446335677cbe4cb549495636a0535f3bd commit bc20205c91c9920361d12b15d253d4997dba494a Author: Damien Miller Date: Thu Jun 25 09:51:39 2015 +1000 add missing pselect6 patch from Jakub Jelen commit 9d27fb73b4a4e5e99cb880af790d5b1ce44f720a Author: djm@openbsd.org Date: Wed Jun 24 23:47:23 2015 +0000 upstream commit correct test to sshkey_sign(); spotted by Albert S. Upstream-ID: 5f7347f40f0ca6abdaca2edb3bd62f4776518933 commit 7ed01a96a1911d8b4a9ef4f3d064e1923bfad7e3 Author: dtucker@openbsd.org Date: Wed Jun 24 01:49:19 2015 +0000 upstream commit Revert previous commit. We still want to call setgroups in the case where there are zero groups to remove any that we might otherwise inherit (as pointed out by grawity at gmail.com) and since the 2nd argument to setgroups is always a static global it's always valid to dereference in this case. ok deraadt@ djm@ Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01 commit 882f8bf94f79528caa65b0ba71c185d705bb7195 Author: dtucker@openbsd.org Date: Wed Jun 24 01:49:19 2015 +0000 upstream commit Revert previous commit. We still want to call setgroups in the case where there are zero groups to remove any that we might otherwise inherit (as pointed out by grawity at gmail.com) and since the 2nd argument to setgroups is always a static global it's always valid to dereference in this case. ok deraadt@ djm@ Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01 commit 9488538a726951e82b3a4374f3c558d72c80a89b Author: djm@openbsd.org Date: Mon Jun 22 23:42:16 2015 +0000 upstream commit Don't count successful partial authentication as failures in monitor; this may have caused the monitor to refuse multiple authentications that would otherwise have successfully completed; ok markus@ Upstream-ID: eb74b8e506714d0f649bd5c300f762a527af04a3 commit 63b78d003bd8ca111a736e6cea6333da50f5f09b Author: dtucker@openbsd.org Date: Mon Jun 22 12:29:57 2015 +0000 upstream commit Don't call setgroups if we have zero groups; there's no guarantee that it won't try to deref the pointer. Based on a patch from mail at quitesimple.org, ok djm deraadt Upstream-ID: 2fff85e11d7a9a387ef7fddf41fbfaf566708ab1 commit 5c15e22c691c79a47747bcf5490126656f97cecd Author: Damien Miller Date: Thu Jun 18 15:07:56 2015 +1000 fix syntax error commit 596dbca82f3f567fb3d2d69af4b4e1d3ba1e6403 Author: jsing@openbsd.org Date: Mon Jun 15 18:44:22 2015 +0000 upstream commit If AuthorizedPrincipalsCommand is specified, however AuthorizedPrincipalsFile is not (or is set to "none"), authentication will potentially fail due to key_cert_check_authority() failing to locate a principal that matches the username, even though an authorized principal has already been matched in the output of the subprocess. Fix this by using the same logic to determine if pw->pw_name should be passed, as is used to determine if a authorized principal must be matched earlier on. ok djm@ Upstream-ID: 43b42302ec846b0ea68aceb40677245391b9409d commit aff3e94c0d75d0d0fa84ea392b50ab04f8c57905 Author: jsing@openbsd.org Date: Mon Jun 15 18:42:19 2015 +0000 upstream commit Make the arguments to match_principals_command() similar to match_principals_file(), by changing the last argument a struct sshkey_cert * and dereferencing key->cert in the caller. No functional change. ok djm@ Upstream-ID: 533f99b844b21b47342b32b62e198dfffcf8651c commit 97e2e1596c202a4693468378b16b2353fd2d6c5e Author: Damien Miller Date: Wed Jun 17 14:36:54 2015 +1000 trivial optimisation for seccomp-bpf When doing arg inspection and the syscall doesn't match, skip past the instruction that reloads the syscall into the accumulator, since the accumulator hasn't been modified at this point. commit 99f33d7304893bd9fa04d227cb6e870171cded19 Author: Damien Miller Date: Wed Jun 17 10:50:51 2015 +1000 aarch64 support for seccomp-bpf sandbox Also resort and tidy syscall list. Based on patches by Jakub Jelen bz#2361; ok dtucker@ commit 4ef702e1244633c1025ec7cfe044b9ab267097bf Author: djm@openbsd.org Date: Mon Jun 15 01:32:50 2015 +0000 upstream commit return failure on RSA signature error; reported by Albert S Upstream-ID: e61bb93dbe0349625807b0810bc213a6822121fa commit a170f22baf18af0b1acf2788b8b715605f41a1f9 Author: Tim Rice Date: Tue Jun 9 22:41:13 2015 -0700 Fix t12 rules for out of tree builds. commit ec04dc4a5515c913121bc04ed261857e68fa5c18 Author: millert@openbsd.org Date: Fri Jun 5 15:13:13 2015 +0000 upstream commit For "ssh -L 12345:/tmp/sock" don't fail with "No forward host name." (we have a path, not a host name). Based on a diff from Jared Yanovich. OK djm@ Upstream-ID: 2846b0a8c7de037e33657f95afbd282837fc213f commit 732d61f417a6aea0aa5308b59cb0f563bcd6edd6 Author: djm@openbsd.org Date: Fri Jun 5 03:44:14 2015 +0000 upstream commit typo: accidental repetition; bz#2386 Upstream-ID: 45e620d99f6bc301e5949d34a54027374991c88b commit adfb24c69d1b6f5e758db200866c711e25a2ba73 Author: Darren Tucker Date: Fri Jun 5 14:51:40 2015 +1000 Add Linux powerpc64le and powerpcle entries. Stopgap to resolve bz#2409 because we are so close to release and will update config.guess and friends shortly after the release. ok djm@ commit a1195a0fdc9eddddb04d3e9e44c4775431cb77da Merge: 6397eed d2480bc Author: Tim Rice Date: Wed Jun 3 21:43:13 2015 -0700 Merge branch 'master' of git.mindrot.org:/var/git/openssh commit 6397eedf953b2b973d2d7cbb504ab501a07f8ddc Author: Tim Rice Date: Wed Jun 3 21:41:11 2015 -0700 Remove unneeded backslashes. Patch from Ãngel González commit d2480bcac1caf31b03068de877a47d6e1027bf6d Author: Darren Tucker Date: Thu Jun 4 14:10:55 2015 +1000 Remove redundant include of stdarg.h. bz#2410 commit 5e67859a623826ccdf2df284cbb37e2d8e2787eb Author: djm@openbsd.org Date: Tue Jun 2 09:10:40 2015 +0000 upstream commit mention CheckHostIP adding addresses to known_hosts; bz#1993; ok dtucker@ Upstream-ID: fd44b68440fd0dc29abf9f2d3f703d74a2396cb7 commit d7a58bbac6583e33fd5eca8e2c2cc70c57617818 Author: Darren Tucker Date: Tue Jun 2 20:15:26 2015 +1000 Replace strcpy with strlcpy. ok djm, sanity check by Corinna Vinschen. commit 51a1c2115265c6e80ede8a5c9dccada9aeed7143 Author: Damien Miller Date: Fri May 29 18:27:21 2015 +1000 skip, rather than fatal when run without SUDO set commit 599f01142a376645b15cbc9349d7e8975e1cf245 Author: Damien Miller Date: Fri May 29 18:03:15 2015 +1000 fix merge botch that left ",," in KEX algs commit 0c2a81dfc21822f2423edd30751e5ec53467b347 Author: Damien Miller Date: Fri May 29 17:08:28 2015 +1000 re-enable SSH protocol 1 at compile time commit db438f9285d64282d3ac9e8c0944f59f037c0151 Author: djm@openbsd.org Date: Fri May 29 03:05:13 2015 +0000 upstream commit make this work without SUDO set; ok dtucker@ Upstream-Regress-ID: bca88217b70bce2fe52b23b8e06bdeb82d98c715 commit 1d9a2e2849c9864fe75daabf433436341c968e14 Author: djm@openbsd.org Date: Thu May 28 07:37:31 2015 +0000 upstream commit wrap all moduli-related code in #ifdef WITH_OPENSSL. based on patch from Reuben Hawkins; bz#2388 feedback and ok dtucker@ Upstream-ID: d80cfc8be3e6ec65b3fac9e87c4466533b31b7cf commit 496aeb25bc2d6c434171292e4714771b594bd00e Author: dtucker@openbsd.org Date: Thu May 28 05:41:29 2015 +0000 upstream commit Increase the allowed length of the known host file name in the log message to be consistent with other cases. Part of bz#1993, ok deraadt. Upstream-ID: a9e97567be49f25daf286721450968251ff78397 commit dd2cfeb586c646ff8d70eb93567b2e559ace5b14 Author: dtucker@openbsd.org Date: Thu May 28 05:09:45 2015 +0000 upstream commit Fix typo (keywork->keyword) Upstream-ID: 8aacd0f4089c0a244cf43417f4f9045dfaeab534 commit 9cc6842493fbf23025ccc1edab064869640d3bec Author: djm@openbsd.org Date: Thu May 28 04:50:53 2015 +0000 upstream commit add error message on ftruncate failure; bz#2176 Upstream-ID: cbcc606e0b748520c74a210d8f3cc9718d3148cf commit d1958793a0072c22be26d136dbda5ae263e717a0 Author: djm@openbsd.org Date: Thu May 28 04:40:13 2015 +0000 upstream commit make ssh-keygen default to ed25519 keys when compiled without OpenSSL; bz#2388, ok dtucker@ Upstream-ID: 85a471fa6d3fa57a7b8e882d22cfbfc1d84cdc71 commit 3ecde664c9fc5fb3667aedf9e6671462600f6496 Author: dtucker@openbsd.org Date: Wed May 27 23:51:10 2015 +0000 upstream commit Reorder client proposal to prefer diffie-hellman-group-exchange-sha1 over diffie-hellman-group14-sha1. ok djm@ Upstream-ID: 552c08d47347c3ee1a9a57d88441ab50abe17058 commit 40f64292b907afd0a674fdbf3e4c2356d17a7d68 Author: dtucker@openbsd.org Date: Wed May 27 23:39:18 2015 +0000 upstream commit Add a stronger (4k bit) fallback group that sshd can use when the moduli file is missing or broken, sourced from RFC3526. bz#2302, ok markus@ (earlier version), djm@ Upstream-ID: b635215746a25a829d117673d5e5a76d4baee7f4 commit 5ab7d5fa03ad55bc438fab45dfb3aeb30a3c237a Author: Darren Tucker Date: Thu May 28 10:03:40 2015 +1000 New moduli file from OpenBSD, removing 1k groups. Remove 1k bit groups. ok deraadt@, markus@ commit a71ba58adf34e599f30cdda6e9b93ae6e3937eea Author: djm@openbsd.org Date: Wed May 27 05:15:02 2015 +0000 upstream commit support PKCS#11 devices with external PIN entry devices bz#2240, based on patch from Dirk-Willem van Gulik; feedback and ok dtucker@ Upstream-ID: 504568992b55a8fc984375242b1bd505ced61b0d commit b282fec1aa05246ed3482270eb70fc3ec5f39a00 Author: dtucker@openbsd.org Date: Tue May 26 23:23:40 2015 +0000 upstream commit Cap DH-GEX group size at 4kbits for Cisco implementations. Some of them will choke when asked for preferred sizes >4k instead of returning the 4k group that they do have. bz#2209, ok djm@ Upstream-ID: 54b863a19713446b7431f9d06ad0532b4fcfef8d commit 3e91b4e8b0dc2b4b7e7d42cf6e8994a32e4cb55e Author: djm@openbsd.org Date: Sun May 24 23:39:16 2015 +0000 upstream commit add missing 'c' option to getopt(), case statement was already there; from Felix Bolte Upstream-ID: 9b19b4e2e0b54d6fefa0dfac707c51cf4bae3081 commit 64a89ec07660abba4d0da7c0095b7371c98bab62 Author: jsg@openbsd.org Date: Sat May 23 14:28:37 2015 +0000 upstream commit fix a memory leak in an error path ok markus@ dtucker@ Upstream-ID: bc1da0f205494944918533d8780fde65dff6c598 commit f948737449257d2cb83ffcfe7275eb79b677fd4a Author: djm@openbsd.org Date: Fri May 22 05:28:45 2015 +0000 upstream commit mention ssh-keygen -E for comparing legacy MD5 fingerprints; bz#2332 Upstream-ID: 079a3669549041dbf10dbc072d9563f0dc3b2859 commit 0882332616e4f0272c31cc47bf2018f9cb258a4e Author: djm@openbsd.org Date: Fri May 22 04:45:52 2015 +0000 upstream commit Reorder EscapeChar option parsing to avoid a single-byte out- of-bounds read. bz#2396 from Jaak Ristioja; ok dtucker@ Upstream-ID: 1dc6b5b63d1c8d9a88619da0b27ade461d79b060 commit d7c31da4d42c115843edee2074d7d501f8804420 Author: djm@openbsd.org Date: Fri May 22 03:50:02 2015 +0000 upstream commit add knob to relax GSSAPI host credential check for multihomed hosts bz#928, patch by Simon Wilkinson; ok dtucker (kerberos/GSSAPI is not compiled by default on OpenBSD) Upstream-ID: 15ddf1c6f7fd9d98eea9962f480079ae3637285d commit aa72196a00be6e0b666215edcffbc10af234cb0e Author: Darren Tucker Date: Fri May 22 17:49:46 2015 +1000 Include signal.h for sig_atomic_t, used by kex.h. bz#2402, from tomas.kuthan at oracle com. commit 8b02481143d75e91c49d1bfae0876ac1fbf9511a Author: Darren Tucker Date: Fri May 22 12:47:24 2015 +1000 Import updated moduli file from OpenBSD. commit 4739e8d5e1c0be49624082bd9f6b077e9e758db9 Author: djm@openbsd.org Date: Thu May 21 12:01:19 2015 +0000 upstream commit Support "ssh-keygen -lF hostname" to find search known_hosts and print key hashes. Already advertised by ssh-keygen(1), but not delivered by code; ok dtucker@ Upstream-ID: 459e0e2bf39825e41b0811c336db2d56a1c23387 commit e97201feca10b5196da35819ae516d0b87cf3a50 Author: Damien Miller Date: Thu May 21 17:55:15 2015 +1000 conditionalise util.h inclusion commit 13640798c7dd011ece0a7d02841fe48e94cfa0e0 Author: djm@openbsd.org Date: Thu May 21 06:44:25 2015 +0000 upstream commit regress test for AuthorizedPrincipalsCommand Upstream-Regress-ID: c658fbf1ab6b6011dc83b73402322e396f1e1219 commit 84452c5d03c21f9bfb28c234e0dc1dc67dd817b1 Author: djm@openbsd.org Date: Thu May 21 06:40:02 2015 +0000 upstream commit regress test for AuthorizedKeysCommand arguments Upstream-Regress-ID: bbd65c13c6b3be9a442ec115800bff9625898f12 commit bcc50d816187fa9a03907ac1f3a52f04a52e10d1 Author: djm@openbsd.org Date: Thu May 21 06:43:30 2015 +0000 upstream commit add AuthorizedPrincipalsCommand that allows getting authorized_principals from a subprocess rather than a file, which is quite useful in deployments with large userbases feedback and ok markus@ Upstream-ID: aa1bdac7b16fc6d2fa3524ef08f04c7258d247f6 commit 24232a3e5ab467678a86aa67968bbb915caffed4 Author: djm@openbsd.org Date: Thu May 21 06:38:35 2015 +0000 upstream commit support arguments to AuthorizedKeysCommand bz#2081 loosely based on patch by Sami Hartikainen feedback and ok markus@ Upstream-ID: b080387a14aa67dddd8ece67c00f268d626541f7 commit d80fbe41a57c72420c87a628444da16d09d66ca7 Author: djm@openbsd.org Date: Thu May 21 04:55:51 2015 +0000 upstream commit refactor: split base64 encoding of pubkey into its own sshkey_to_base64() function and out of sshkey_write(); ok markus@ Upstream-ID: 54fc38f5832e9b91028900819bda46c3959a0c1a commit 7cc44ef74133a473734bbcbd3484f24d6a7328c5 Author: deraadt@openbsd.org Date: Mon May 18 15:06:05 2015 +0000 upstream commit getentropy() and sendsyslog() have been around long enough. openssh-portable may want the #ifdef's but not base. discussed with djm few weeks back Upstream-ID: 0506a4334de108e3fb6c66f8d6e0f9c112866926 commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e Author: dtucker@openbsd.org Date: Fri May 15 05:44:21 2015 +0000 upstream commit Use a salted hash of the lock passphrase instead of plain text and do constant-time comparisons of it. Should prevent leaking any information about it via timing, pointed out by Ryan Castellucci. Add a 0.1s incrementing delay for each failed unlock attempt up to 10s. ok markus@ (earlier version), djm@ Upstream-ID: c599fcc325aa1cc65496b25220b622d22208c85f commit d028d5d3a697c71b21e4066d8672cacab3caa0a8 Author: Damien Miller Date: Tue May 5 19:10:58 2015 +1000 upstream commit - tedu@cvs.openbsd.org 2015/01/12 03:20:04 [bcrypt_pbkdf.c] rename blocks to words. bcrypt "blocks" are unrelated to blowfish blocks, nor are they the same size. commit f6391d4e59b058984163ab28f4e317e7a72478f1 Author: Damien Miller Date: Tue May 5 19:10:23 2015 +1000 upstream commit - deraadt@cvs.openbsd.org 2015/01/08 00:30:07 [bcrypt_pbkdf.c] declare a local version of MIN(), call it MINIMUM() commit 8ac6b13cc9113eb47cd9e86c97d7b26b4b71b77f Author: Damien Miller Date: Tue May 5 19:09:46 2015 +1000 upstream commit - djm@cvs.openbsd.org 2014/12/30 01:41:43 [bcrypt_pbkdf.c] typo in comment: ouput => output commit 1f792489d5cf86a4f4e3003e6e9177654033f0f2 Author: djm@openbsd.org Date: Mon May 4 06:10:48 2015 +0000 upstream commit Remove pattern length argument from match_pattern_list(), we only ever use it for strlen(pattern). Prompted by hanno AT hboeck.de pointing an out-of-bound read error caused by an incorrect pattern length found using AFL and his own tools. ok markus@ commit 639d6bc57b1942393ed12fb48f00bc05d4e093e4 Author: djm@openbsd.org Date: Fri May 1 07:10:01 2015 +0000 upstream commit refactor ssh_dispatch_run_fatal() to use sshpkt_fatal() to better report error conditions. Teach sshpkt_fatal() about ECONNRESET. Improves error messages on TCP connection resets. bz#2257 ok dtucker@ commit 9559d7de34c572d4d3fd990ca211f8ec99f62c4d Author: djm@openbsd.org Date: Fri May 1 07:08:08 2015 +0000 upstream commit a couple of parse targets were missing activep checks, causing them to be misapplied in match context; bz#2272 diagnosis and original patch from Sami Hartikainen ok dtucker@ commit 7e8528cad04b2775c3b7db08abf8fb42e47e6b2a Author: djm@openbsd.org Date: Fri May 1 04:17:51 2015 +0000 upstream commit make handling of AuthorizedPrincipalsFile=none more consistent with other =none options; bz#2288 from Jakub Jelen; ok dtucker@ commit ca430d4d9cc0f62eca3b1fb1e2928395b7ce80f7 Author: djm@openbsd.org Date: Fri May 1 04:03:20 2015 +0000 upstream commit remove failed remote forwards established by muliplexing from the list of active forwards; bz#2363, patch mostly by Yoann Ricordel; ok dtucker@ commit 8312cfb8ad88657517b3e23ac8c56c8e38eb9792 Author: djm@openbsd.org Date: Fri May 1 04:01:58 2015 +0000 upstream commit reduce stderr spam when using ssh -S /path/mux -O forward -R 0:... ok dtucker@ commit 179be0f5e62f1f492462571944e45a3da660d82b Author: djm@openbsd.org Date: Fri May 1 03:23:51 2015 +0000 upstream commit prevent authorized_keys options picked up on public key tests without a corresponding private key authentication being applied to other authentication methods. Reported by halex@, ok markus@ commit a42d67be65b719a430b7fcaba2a4e4118382723a Author: djm@openbsd.org Date: Fri May 1 03:20:54 2015 +0000 upstream commit Don't make parsing of authorized_keys' environment= option conditional on PermitUserEnv - always parse it, but only use the result if the option is enabled. This prevents the syntax of authorized_keys changing depending on which sshd_config options were enabled. bz#2329; based on patch from coladict AT gmail.com, ok dtucker@ commit e661a86353e11592c7ed6a847e19a83609f49e77 Author: djm@openbsd.org Date: Mon May 4 06:10:48 2015 +0000 upstream commit Remove pattern length argument from match_pattern_list(), we only ever use it for strlen(pattern). Prompted by hanno AT hboeck.de pointing an out-of-bound read error caused by an incorrect pattern length found using AFL and his own tools. ok markus@ commit 0ef1de742be2ee4b10381193fe90730925b7f027 Author: dtucker@openbsd.org Date: Thu Apr 23 05:01:19 2015 +0000 upstream commit Add a simple regression test for sshd's configuration parser. Right now, all it does is run the output of sshd -T back through itself and ensure the output is valid and invariant. commit 368f83c793275faa2c52f60eaa9bdac155c4254b Author: djm@openbsd.org Date: Wed Apr 22 01:38:36 2015 +0000 upstream commit use correct key for nested certificate test commit 8d4d1bfddbbd7d21f545dc6997081d1ea1fbc99a Author: djm@openbsd.org Date: Fri May 1 07:11:47 2015 +0000 upstream commit mention that the user's shell from /etc/passwd is used for commands too; bz#1459 ok dtucker@ commit 5ab283d0016bbc9d4d71e8e5284d011bc5a930cf Author: djm@openbsd.org Date: Fri May 8 07:29:00 2015 +0000 upstream commit whitespace Upstream-Regress-ID: 6b708a3e709d5b7fd37890f874bafdff1f597519 commit 8377d5008ad260048192e1e56ad7d15a56d103dd Author: djm@openbsd.org Date: Fri May 8 07:26:13 2015 +0000 upstream commit whitespace at EOL Upstream-Regress-ID: 9c48911643d5b05173b36a012041bed4080b8554 commit c28a3436fa8737709ea88e4437f8f23a6ab50359 Author: djm@openbsd.org Date: Fri May 8 06:45:13 2015 +0000 upstream commit moar whitespace at eol Upstream-ID: 64eaf872a3ba52ed41e494287e80d40aaba4b515 commit 2b64c490468fd4ca35ac8d5cc31c0520dc1508bb Author: djm@openbsd.org Date: Fri May 8 06:41:56 2015 +0000 upstream commit whitespace at EOL Upstream-ID: 57bcf67d666c6fc1ad798aee448fdc3f70f7ec2c commit 4e636cf201ce6e7e3b9088568218f9d4e2c51712 Author: djm@openbsd.org Date: Fri May 8 03:56:51 2015 +0000 upstream commit whitespace at EOL commit 38b8272f823dc1dd4e29dbcee83943ed48bb12fa Author: dtucker@openbsd.org Date: Mon May 4 01:47:53 2015 +0000 upstream commit Use diff w/out -u for better portability commit 297060f42d5189a4065ea1b6f0afdf6371fb0507 Author: dtucker@openbsd.org Date: Fri May 8 03:25:07 2015 +0000 upstream commit Use xcalloc for permitted_adm_opens instead of xmalloc to ensure it's zeroed. Fixes post-auth crash with permitopen=none. bz#2355, ok djm@ commit 63ebf019be863b2d90492a85e248cf55a6e87403 Author: djm@openbsd.org Date: Fri May 8 03:17:49 2015 +0000 upstream commit don't choke on new-format private keys encrypted with an AEAD cipher; bz#2366, patch from Ron Frederick; ok markus@ commit f8484dac678ab3098ae522a5f03bb2530f822987 Author: dtucker@openbsd.org Date: Wed May 6 05:45:17 2015 +0000 upstream commit Clarify pseudo-terminal request behaviour and use "pseudo-terminal" consistently. bz#1716, ok jmc@ "I like it" deraadt@. commit ea139507bef8bad26e86ed99a42c7233ad115c38 Author: dtucker@openbsd.org Date: Wed May 6 04:07:18 2015 +0000 upstream commit Blacklist DH-GEX for specific PuTTY versions known to send non-RFC4419 DH-GEX messages rather than all versions of PuTTY. According to Simon Tatham, 0.65 and newer versions will send RFC4419 DH-GEX messages. ok djm@ commit b58234f00ee3872eb84f6e9e572a9a34e902e36e Author: dtucker@openbsd.org Date: Tue May 5 10:17:49 2015 +0000 upstream commit WinSCP doesn't implement RFC4419 DH-GEX so flag it so we don't offer that KEX method. ok markus@ commit d5b1507a207253b39e810e91e68f9598691b7a29 Author: jsg@openbsd.org Date: Tue May 5 02:48:17 2015 +0000 upstream commit use the sizeof the struct not the sizeof a pointer to the struct in ssh_digest_start() This file is only used if ssh is built with OPENSSL=no ok markus@ commit a647b9b8e616c231594b2710c925d31b1b8afea3 Author: Darren Tucker Date: Fri May 8 11:07:27 2015 +1000 Put brackets around mblen() compat constant. This might help with the reported problem cross compiling for Android ("error: expected identifier or '(' before numeric constant") but shouldn't hurt in any case. commit d1680d36e17244d9af3843aeb5025cb8e40d6c07 Author: Darren Tucker Date: Thu Apr 30 09:18:11 2015 +1000 xrealloc -> xreallocarray in portable code too. commit 531a57a3893f9fcd4aaaba8c312b612bbbcc021e Author: dtucker@openbsd.org Date: Wed Apr 29 03:48:56 2015 +0000 upstream commit Allow ListenAddress, Port and AddressFamily in any order. bz#68, ok djm@, jmc@ (for the man page bit). commit c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f Author: jmc@openbsd.org Date: Tue Apr 28 13:47:38 2015 +0000 upstream commit enviroment -> environment: apologies to darren for not spotting that first time round... commit 43beea053db191cac47c2cd8d3dc1930158aff1a Author: dtucker@openbsd.org Date: Tue Apr 28 10:25:15 2015 +0000 upstream commit Fix typo in previous commit 85b96ef41374f3ddc9139581f87da09b2cd9199e Author: dtucker@openbsd.org Date: Tue Apr 28 10:17:58 2015 +0000 upstream commit Document that the TERM environment variable is not subject to SendEnv and AcceptEnv. bz#2386, based loosely on a patch from jjelen at redhat, help and ok jmc@ commit 88a7c598a94ff53f76df228eeaae238d2d467565 Author: djm@openbsd.org Date: Mon Apr 27 21:42:48 2015 +0000 upstream commit Make sshd default to PermitRootLogin=no; ok deraadt@ rpe@ commit 734226b4480a6c736096c729fcf6f391400599c7 Author: djm@openbsd.org Date: Mon Apr 27 01:52:30 2015 +0000 upstream commit fix compilation with OPENSSL=no; ok dtucker@ commit a4b9d2ce1eb7703eaf0809b0c8a82ded8aa4f1c6 Author: dtucker@openbsd.org Date: Mon Apr 27 00:37:53 2015 +0000 upstream commit Include stdio.h for FILE (used in sshkey.h) so it compiles with OPENSSL=no. commit dbcc652f4ca11fe04e5930c7ef18a219318c6cda Author: djm@openbsd.org Date: Mon Apr 27 00:21:21 2015 +0000 upstream commit allow "sshd -f none" to skip reading the config file, much like "ssh -F none" does. ok dtucker commit b7ca276fca316c952f0b90f5adb1448c8481eedc Author: jmc@openbsd.org Date: Fri Apr 24 06:26:49 2015 +0000 upstream commit combine -Dd onto one line and update usage(); commit 2ea974630d7017e4c7666d14d9dc939707613e96 Author: djm@openbsd.org Date: Fri Apr 24 05:26:44 2015 +0000 upstream commit add ssh-agent -D to leave ssh-agent in foreground without enabling debug mode; bz#2381 ok dtucker@ commit 8ac2ffd7aa06042f6b924c87139f2fea5c5682f7 Author: deraadt@openbsd.org Date: Fri Apr 24 01:36:24 2015 +0000 upstream commit 2*len -> use xreallocarray() ok djm commit 657a5fbc0d0aff309079ff8fb386f17e964963c2 Author: deraadt@openbsd.org Date: Fri Apr 24 01:36:00 2015 +0000 upstream commit rename xrealloc() to xreallocarray() since it follows that form. ok djm commit 1108ae242fdd2c304307b68ddf46aebe43ebffaa Author: dtucker@openbsd.org Date: Thu Apr 23 04:59:10 2015 +0000 upstream commit Two small fixes for sshd -T: ListenAddress'es are added to a list head so reverse the order when printing them to ensure the behaviour remains the same, and print StreamLocalBindMask as octal with leading zero. ok deraadt@ commit bd902b8473e1168f19378d5d0ae68d0c203525df Author: dtucker@openbsd.org Date: Thu Apr 23 04:53:53 2015 +0000 upstream commit Check for and reject missing arguments for VersionAddendum and ForceCommand. bz#2281, patch from plautrba at redhat com, ok djm@ commit ca42c1758575e592239de1d5755140e054b91a0d Author: djm@openbsd.org Date: Wed Apr 22 01:24:01 2015 +0000 upstream commit unknown certificate extensions are non-fatal, so don't fatal when they are encountered; bz#2387 reported by Bob Van Zant; ok dtucker@ commit 39bfbf7caad231cc4bda6909fb1af0705bca04d8 Author: jsg@openbsd.org Date: Tue Apr 21 07:01:00 2015 +0000 upstream commit Add back a backslash removed in rev 1.42 so KEX_SERVER_ENCRYPT will include aes again. ok deraadt@ commit 6b0d576bb87eca3efd2b309fcfe4edfefc289f9c Author: djm@openbsd.org Date: Fri Apr 17 13:32:09 2015 +0000 upstream commit s/recommended/required/ that private keys be og-r this wording change was made a while ago but got accidentally reverted commit 44a8e7ce6f3ab4c2eb1ae49115c210b98e53c4df Author: djm@openbsd.org Date: Fri Apr 17 13:25:52 2015 +0000 upstream commit don't try to cleanup NULL KEX proposals in kex_prop_free(); found by Jukka Taimisto and Markus Hietava commit 3038a191872d2882052306098c1810d14835e704 Author: djm@openbsd.org Date: Fri Apr 17 13:19:22 2015 +0000 upstream commit use error/logit/fatal instead of fprintf(stderr, ...) and exit(0), fix a few errors that were being printed to stdout instead of stderr and a few non-errors that were going to stderr instead of stdout bz#2325; ok dtucker commit a58be33cb6cd24441fa7e634db0e5babdd56f07f Author: djm@openbsd.org Date: Fri Apr 17 13:16:48 2015 +0000 upstream commit debug log missing DISPLAY environment when X11 forwarding requested; bz#1682 ok dtucker@ commit 17d4d9d9fbc8fb80e322f94d95eecc604588a474 Author: djm@openbsd.org Date: Fri Apr 17 04:32:31 2015 +0000 upstream commit don't call record_login() in monitor when UseLogin is enabled; bz#278 reported by drk AT sgi.com; ok dtucker commit 40132ff87b6cbc3dc05fb5df2e9d8e3afa06aafd Author: dtucker@openbsd.org Date: Fri Apr 17 04:12:35 2015 +0000 upstream commit Add some missing options to sshd -T and fix the output of VersionAddendum HostCertificate. bz#2346, patch from jjelen at redhat com, ok djm. commit 6cc7cfa936afde2d829e56ee6528c7ea47a42441 Author: dtucker@openbsd.org Date: Thu Apr 16 23:25:50 2015 +0000 upstream commit Document "none" for PidFile XAuthLocation TrustedUserCAKeys and RevokedKeys. bz#2382, feedback from jmc@, ok djm@ commit 15fdfc9b1c6808b26bc54d4d61a38b54541763ed Author: dtucker@openbsd.org Date: Wed Apr 15 23:23:25 2015 +0000 upstream commit Plug leak of address passed to logging. bz#2373, patch from jjelen at redhat, ok markus@ commit bb2289e2a47d465eaaaeff3dee2a6b7777b4c291 Author: dtucker@openbsd.org Date: Tue Apr 14 04:17:03 2015 +0000 upstream commit Output remote username in debug output since with Host and Match it's not always obvious what it will be. bz#2368, ok djm@ commit 70860b6d07461906730632f9758ff1b7c98c695a Author: Darren Tucker Date: Fri Apr 17 10:56:13 2015 +1000 Format UsePAM setting when using sshd -T. Part of bz#2346, patch from jjelen at redhat com. commit ee15d9c9f0720f5a8b0b34e4b10ecf21f9824814 Author: Darren Tucker Date: Fri Apr 17 10:40:23 2015 +1000 Wrap endian.h include inside ifdef (bz#2370). commit 408f4c2ad4a4c41baa7b9b2b7423d875abbfa70b Author: Darren Tucker Date: Fri Apr 17 09:39:58 2015 +1000 Look for '${host}-ar' before 'ar'. This changes configure.ac to look for '${host}-ar' as set by AC_CANONICAL_HOST before looking for the unprefixed 'ar'. Useful when cross-compiling when all your binutils are prefixed. Patch from moben at exherbo org via astrand at lysator liu se and bz#2352. commit 673a1c16ad078d41558247ce739fe812c960acc8 Author: Damien Miller Date: Thu Apr 16 11:40:20 2015 +1000 remove dependency on arpa/telnet.h commit 202d443eeda1829d336595a3cfc07827e49f45ed Author: Darren Tucker Date: Wed Apr 15 15:59:49 2015 +1000 Remove duplicate include of pwd.h. bz#2337, patch from Mordy Ovits. commit 597986493412c499f2bc2209420cb195f97b3668 Author: Damien Miller Date: Thu Apr 9 10:14:48 2015 +1000 platform's with openpty don't need pty_release commit 318be28cda1fd9108f2e6f2f86b0b7589ba2aed0 Author: djm@openbsd.org Date: Mon Apr 13 02:04:08 2015 +0000 upstream commit deprecate ancient, pre-RFC4419 and undocumented SSH2_MSG_KEX_DH_GEX_REQUEST_OLD message; ok markus@ deraadt@ "seems reasonable" dtucker@ commit d8f391caef62378463a0e6b36f940170dadfe605 Author: dtucker@openbsd.org Date: Fri Apr 10 05:16:50 2015 +0000 upstream commit Don't send hostkey advertisments (hostkeys-00@openssh.com) to current versions of Tera Term as they can't handle them. Newer versions should be OK. Patch from Bryan Drewery and IWAMOTO Kouichi, ok djm@ commit 2c2cfe1a1c97eb9a08cc9817fd0678209680c636 Author: djm@openbsd.org Date: Fri Apr 10 00:08:55 2015 +0000 upstream commit include port number if a non-default one has been specified; based on patch from Michael Handler commit 4492a4f222da4cf1e8eab12689196322e27b08c4 Author: djm@openbsd.org Date: Tue Apr 7 23:00:42 2015 +0000 upstream commit treat Protocol=1,2|2,1 as Protocol=2 when compiled without SSH1 support; ok dtucker@ millert@ commit c265e2e6e932efc6d86f6cc885dea33637a67564 Author: miod@openbsd.org Date: Sun Apr 5 15:43:43 2015 +0000 upstream commit Do not use int for sig_atomic_t; spotted by christos@netbsd; ok markus@ commit e7bf3a5eda6a1b02bef6096fed78527ee11e54cc Author: Darren Tucker Date: Tue Apr 7 10:48:04 2015 +1000 Use do{}while(0) for no-op functions. From FreeBSD. commit bb99844abae2b6447272f79e7fa84134802eb4df Author: Darren Tucker Date: Tue Apr 7 10:47:15 2015 +1000 Wrap blf.h include in ifdef. From FreeBSD. commit d9b9b43656091cf0ad55c122f08fadb07dad0abd Author: Darren Tucker Date: Tue Apr 7 09:10:00 2015 +1000 Fix misspellings of regress CONFOPTS env variables. Patch from Bryan Drewery. commit 3f4ea3c9ab1d32d43c9222c4351f58ca11144156 Author: djm@openbsd.org Date: Fri Apr 3 22:17:27 2015 +0000 upstream commit correct return value in pubkey parsing, spotted by Ben Hawkes ok markus@ commit 7da2be0cb9601ed25460c83aa4d44052b967ba0f Author: djm@openbsd.org Date: Tue Mar 31 22:59:01 2015 +0000 upstream commit adapt to recent hostfile.c change: when parsing known_hosts without fully parsing the keys therein, hostkeys_foreach() will now correctly identify KEY_RSA1 keys; ok markus@ miod@ commit 9e1777a0d1c706714b055811c12ab8cc21033e4a Author: markus@openbsd.org Date: Tue Mar 24 20:19:15 2015 +0000 upstream commit use ${SSH} for -Q instead of installed ssh commit ce1b358ea414a2cc88e4430cd5a2ea7fecd9de57 Author: djm@openbsd.org Date: Mon Mar 16 22:46:14 2015 +0000 upstream commit make CLEANFILES clean up more of the tests' droppings commit 398f9ef192d820b67beba01ec234d66faca65775 Author: djm@openbsd.org Date: Tue Mar 31 22:57:06 2015 +0000 upstream commit downgrade error() for known_hosts parse errors to debug() to quiet warnings from ssh1 keys present when compiled !ssh1. also identify ssh1 keys when scanning, even when compiled !ssh1 ok markus@ miod@ commit 9a47ab80030a31f2d122b8fd95bd48c408b9fcd9 Author: djm@openbsd.org Date: Tue Mar 31 22:55:50 2015 +0000 upstream commit fd leak for !ssh1 case; found by unittests; ok markus@ commit c9a0805a6280681901c270755a7cd630d7c5280e Author: djm@openbsd.org Date: Tue Mar 31 22:55:24 2015 +0000 upstream commit don't fatal when a !ssh1 sshd is reexeced from a w/ssh1 listener; reported by miod@; ok miod@ markus@ commit 704d8c88988cae38fb755a6243b119731d223222 Author: tobias@openbsd.org Date: Tue Mar 31 11:06:49 2015 +0000 upstream commit Comments are only supported for RSA1 keys. If a user tried to add one and entered his passphrase, explicitly clear it before exit. This is done in all other error paths, too. ok djm commit 78de1673c05ea2c33e0d4a4b64ecb5186b6ea2e9 Author: jmc@openbsd.org Date: Mon Mar 30 18:28:37 2015 +0000 upstream commit ssh-askpass(1) is the default, overridden by SSH_ASKPASS; diff originally from jiri b; commit 26e0bcf766fadb4a44fb6199386fb1dcab65ad00 Author: djm@openbsd.org Date: Mon Mar 30 00:00:29 2015 +0000 upstream commit fix uninitialised memory read when parsing a config file consisting of a single nul byte. Found by hanno AT hboeck.de using AFL; ok dtucker commit fecede00a76fbb33a349f5121c0b2f9fbc04a777 Author: markus@openbsd.org Date: Thu Mar 26 19:32:19 2015 +0000 upstream commit sigp and lenp are not optional in ssh_agent_sign(); ok djm@ commit 1b0ef3813244c78669e6d4d54c624f600945327d Author: naddy@openbsd.org Date: Thu Mar 26 12:32:38 2015 +0000 upstream commit don't try to load .ssh/identity by default if SSH1 is disabled; ok markus@ commit f9b78852379b74a2d14e6fc94fe52af30b7e9c31 Author: djm@openbsd.org Date: Thu Mar 26 07:00:04 2015 +0000 upstream commit ban all-zero curve25519 keys as recommended by latest CFRG curves draft; ok markus commit b8afbe2c1aaf573565e4da775261dfafc8b1ba9c Author: djm@openbsd.org Date: Thu Mar 26 06:59:28 2015 +0000 upstream commit relax bits needed check to allow diffie-hellman-group1-sha1 key exchange to complete for chacha20-poly1305 was selected as symmetric cipher; ok markus commit 47842f71e31da130555353c1d57a1e5a8937f1c0 Author: markus@openbsd.org Date: Wed Mar 25 19:29:58 2015 +0000 upstream commit ignore v1 errors on ssh-add -D; only try v2 keys on -l/-L (unless WITH_SSH1) ok djm@ commit 5f57e77f91bf2230c09eca96eb5ecec39e5f2da6 Author: markus@openbsd.org Date: Wed Mar 25 19:21:48 2015 +0000 upstream commit unbreak ssh_agent_sign (lenp vs *lenp) commit 4daeb67181054f2a377677fac919ee8f9ed3490e Author: markus@openbsd.org Date: Tue Mar 24 20:10:08 2015 +0000 upstream commit don't leak 'setp' on error; noted by Nicholas Lemonias; ok djm@ commit 7d4f96f9de2a18af0d9fa75ea89a4990de0344f5 Author: markus@openbsd.org Date: Tue Mar 24 20:09:11 2015 +0000 upstream commit consistent check for NULL as noted by Nicholas Lemonias; ok djm@ commit df100be51354e447d9345cf1ec22e6013c0eed50 Author: markus@openbsd.org Date: Tue Mar 24 20:03:44 2015 +0000 upstream commit correct fmt-string for size_t as noted by Nicholas Lemonias; ok djm@ commit a22b9ef21285e81775732436f7c84a27bd3f71e0 Author: djm@openbsd.org Date: Tue Mar 24 09:17:21 2015 +0000 upstream commit promote chacha20-poly1305@openssh.com to be the default cipher; ok markus commit 2aa9da1a3b360cf7b13e96fe1521534b91501fb5 Author: djm@openbsd.org Date: Tue Mar 24 01:29:19 2015 +0000 upstream commit Compile-time disable SSH protocol 1. You can turn it back on using the Makefile.inc knob if you need it to talk to ancient devices. commit 53097b2022154edf96b4e8526af5666f979503f7 Author: djm@openbsd.org Date: Tue Mar 24 01:11:12 2015 +0000 upstream commit fix double-negative error message "ssh1 is not unsupported" commit 5c27e3b6ec2db711dfcd40e6359c0bcdd0b62ea9 Author: djm@openbsd.org Date: Mon Mar 23 06:06:38 2015 +0000 upstream commit for ssh-keygen -A, don't try (and fail) to generate ssh v.1 keys when compiled without SSH1 support RSA/DSA/ECDSA keys when compiled without OpenSSL based on patch by Mike Frysinger; bz#2369 commit 725fd22a8c41db7de73a638539a5157b7e4424ae Author: djm@openbsd.org Date: Wed Mar 18 01:44:21 2015 +0000 upstream commit KRL support doesn't need OpenSSL anymore, remove #ifdefs from around call commit b07011c18e0b2e172c5fd09d21fb159a0bf5fcc7 Author: djm@openbsd.org Date: Mon Mar 16 11:09:52 2015 +0000 upstream commit #if 0 some more arrays used only for decrypting (we don't use since we only need encrypt for AES-CTR) commit 1cb3016635898d287e9d58b50c430995652d5358 Author: jsg@openbsd.org Date: Wed Mar 11 00:48:39 2015 +0000 upstream commit add back the changes from rev 1.206, djm reverted this by mistake in rev 1.207 commit 4d24b3b6a4a6383e05e7da26d183b79fa8663697 Author: Damien Miller Date: Fri Mar 20 09:11:59 2015 +1100 remove error() accidentally inserted for debugging pointed out by Christian Hesse commit 9f82e5a9042f2d872e98f48a876fcab3e25dd9bb Author: Tim Rice Date: Mon Mar 16 22:49:20 2015 -0700 portability fix: Solaris systems may not have a grep that understands -q commit 8ef691f7d9ef500257a549d0906d78187490668f Author: Damien Miller Date: Wed Mar 11 10:35:26 2015 +1100 fix compile with clang commit 4df590cf8dc799e8986268d62019b487a8ed63ad Author: Damien Miller Date: Wed Mar 11 10:02:39 2015 +1100 make unit tests work for !OPENSSH_HAS_ECC commit 307bb40277ca2c32e97e61d70d1ed74b571fd6ba Author: djm@openbsd.org Date: Sat Mar 7 04:41:48 2015 +0000 upstream commit unbreak for w/SSH1 (default) case; ok markus@ deraadt@ commit b44ee0c998fb4c5f3c3281f2398af5ce42840b6f Author: Damien Miller Date: Thu Mar 5 18:39:20 2015 -0800 unbreak hostkeys test for w/ SSH1 case commit 55e5bdeb519cb60cc18b7ba0545be581fb8598b4 Author: djm@openbsd.org Date: Fri Mar 6 01:40:56 2015 +0000 upstream commit fix sshkey_certify() return value for unsupported key types; ok markus@ deraadt@ commit be8f658e550a434eac04256bfbc4289457a24e99 Author: Damien Miller Date: Wed Mar 4 15:38:03 2015 -0800 update version numbers to match version.h commit ac5e8acefa253eb5e5ba186e34236c0e8007afdc Author: djm@openbsd.org Date: Wed Mar 4 23:22:35 2015 +0000 upstream commit make these work with !SSH1; ok markus@ deraadt@ commit 2f04af92f036b0c87a23efb259c37da98cd81fe6 Author: djm@openbsd.org Date: Wed Mar 4 21:12:59 2015 +0000 upstream commit make ssh-add -D work with !SSH1 agent commit a05adf95d2af6abb2b7826ddaa7a0ec0cdc1726b Author: Damien Miller Date: Wed Mar 4 00:55:48 2015 -0800 netcat needs poll.h portability goop commit dad2b1892b4c1b7e58df483a8c5b983c4454e099 Author: markus@openbsd.org Date: Tue Mar 3 22:35:19 2015 +0000 upstream commit make it possible to run tests w/o ssh1 support; ok djm@ commit d48a22601bdd3eec054794c535f4ae8d8ae4c6e2 Author: djm@openbsd.org Date: Wed Mar 4 18:53:53 2015 +0000 upstream commit crank; ok markus, deraadt commit bbffb23daa0b002dd9f296e396a9ab8a5866b339 Author: Damien Miller Date: Tue Mar 3 13:50:27 2015 -0800 more --without-ssh1 fixes commit 6c2039286f503e2012a58a1d109e389016e7a99b Author: Damien Miller Date: Tue Mar 3 13:48:48 2015 -0800 fix merge both that broke --without-ssh1 compile commit 111dfb225478a76f89ecbcd31e96eaf1311b59d3 Author: djm@openbsd.org Date: Tue Mar 3 21:21:13 2015 +0000 upstream commit add SSH1 Makefile knob to make it easier to build without SSH1 support; ok markus@ commit 3f7f5e6c5d2aa3f6710289c1a30119e534e56c5c Author: djm@openbsd.org Date: Tue Mar 3 20:42:49 2015 +0000 upstream commit expand __unused to full __attribute__ for better portability commit 2fab9b0f8720baf990c931e3f68babb0bf9949c6 Author: Damien Miller Date: Wed Mar 4 07:41:27 2015 +1100 avoid warning commit d1bc844322461f882b4fd2277ba9a8d4966573d2 Author: Damien Miller Date: Wed Mar 4 06:31:45 2015 +1100 Revert "define __unused to nothing if not already defined" This reverts commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908. Some system headers have objects named __unused commit 00797e86b2d98334d1bb808f65fa1fd47f328ff1 Author: Damien Miller Date: Wed Mar 4 05:02:45 2015 +1100 check for crypt and DES_crypt in openssl block fixes builds on systems that use DES_crypt; based on patch from Roumen Petrov commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908 Author: Damien Miller Date: Wed Mar 4 04:59:13 2015 +1100 define __unused to nothing if not already defined fixes builds on BSD/OS commit d608a51daad4f14ad6ab43d7cf74ef4801cc3fe9 Author: djm@openbsd.org Date: Tue Mar 3 17:53:40 2015 +0000 upstream commit reorder logic for better portability; patch from Roumen Petrov commit 68d2dfc464fbcdf8d6387884260f9801f4352393 Author: djm@openbsd.org Date: Tue Mar 3 06:48:58 2015 +0000 upstream commit Allow "ssh -Q protocol-version" to list supported SSH protocol versions. Useful for detecting builds without SSH v.1 support; idea and ok markus@ commit 39e2f1229562e1195169905607bc12290d21f021 Author: millert@openbsd.org Date: Sun Mar 1 15:44:40 2015 +0000 upstream commit Make sure we only call getnameinfo() for AF_INET or AF_INET6 sockets. getpeername() of a Unix domain socket may return without error on some systems without actually setting ss_family so getnameinfo() was getting called with ss_family set to AF_UNSPEC. OK djm@ commit e47536ba9692d271b8ad89078abdecf0a1c11707 Author: Damien Miller Date: Sat Feb 28 08:20:11 2015 -0800 portability fixes for regress/netcat.c Mostly avoiding "err(1, NULL)" commit 02973ad5f6f49d8420e50a392331432b0396c100 Author: Damien Miller Date: Sat Feb 28 08:05:27 2015 -0800 twiddle another test for portability from Tom G. Christensen commit f7f3116abf2a6e2f309ab096b08c58d19613e5d0 Author: Damien Miller Date: Fri Feb 27 15:52:49 2015 -0800 twiddle test for portability commit 1ad3a77cc9d5568f5437ff99d377aa7a41859b83 Author: Damien Miller Date: Thu Feb 26 20:33:22 2015 -0800 make regress/netcat.c fd passing (more) portable commit 9e1cfca7e1fe9cf8edb634fc894e43993e4da1ea Author: Damien Miller Date: Thu Feb 26 20:32:58 2015 -0800 create OBJ/valgrind-out before running unittests commit bd58853102cee739f0e115e6d4b5334332ab1442 Author: Damien Miller Date: Wed Feb 25 16:58:22 2015 -0800 valgrind support commit f43d17269194761eded9e89f17456332f4c83824 Author: djm@openbsd.org Date: Thu Feb 26 20:45:47 2015 +0000 upstream commit don't printf NULL key comments; reported by Tom Christensen commit 6e6458b476ec854db33e3e68ebf4f489d0ab3df8 Author: djm@openbsd.org Date: Wed Feb 25 23:05:47 2015 +0000 upstream commit zero cmsgbuf before use; we initialise the bits we use but valgrind still spams warning on it commit a63cfa26864b93ab6afefad0b630e5358ed8edfa Author: djm@openbsd.org Date: Wed Feb 25 19:54:02 2015 +0000 upstream commit fix small memory leak when UpdateHostkeys=no commit e6b950341dd75baa8526f1862bca39e52f5b879b Author: Tim Rice Date: Wed Feb 25 09:56:48 2015 -0800 Revert "Work around finicky USL linker so netcat will build." This reverts commit d1db656021d0cd8c001a6692f772f1de29b67c8b. No longer needed with commit 678e473e2af2e4802f24dd913985864d9ead7fb3 commit 6f621603f9cff2a5d6016a404c96cb2f8ac2dec0 Author: djm@openbsd.org Date: Wed Feb 25 17:29:38 2015 +0000 upstream commit don't leak validity of user in "too many authentication failures" disconnect message; reported by Sebastian Reitenbach commit 6288e3a935494df12519164f52ca5c8c65fc3ca5 Author: naddy@openbsd.org Date: Tue Feb 24 15:24:05 2015 +0000 upstream commit add -v (show ASCII art) to -l's synopsis; ok djm@ commit 678e473e2af2e4802f24dd913985864d9ead7fb3 Author: Darren Tucker Date: Thu Feb 26 04:12:58 2015 +1100 Remove dependency on xmalloc. Remove ssh_get_progname's dependency on xmalloc, which should reduce link order problems. ok djm@ commit 5d5ec165c5b614b03678afdad881f10e25832e46 Author: Darren Tucker Date: Wed Feb 25 15:32:49 2015 +1100 Restrict ECDSA and ECDH tests. ifdef out some more ECDSA and ECDH tests when built against an OpenSSL that does not have eliptic curve functionality. commit 1734e276d99b17e92d4233fac7aef3a3180aaca7 Author: Darren Tucker Date: Wed Feb 25 13:40:45 2015 +1100 Move definition of _NSIG. _NSIG is only unsed in one file, so move it there prevent redefinition warnings reported by Kevin Brott. commit a47ead7c95cfbeb72721066c4da2312e5b1b9f3d Author: Darren Tucker Date: Wed Feb 25 13:17:40 2015 +1100 Add includes.h for compatibility stuff. commit 38806bda6d2e48ad32812b461eebe17672ada771 Author: Damien Miller Date: Tue Feb 24 16:50:06 2015 -0800 include netdb.h to look for MAXHOSTNAMELEN; ok tim commit d1db656021d0cd8c001a6692f772f1de29b67c8b Author: Tim Rice Date: Tue Feb 24 10:42:08 2015 -0800 Work around finicky USL linker so netcat will build. commit cb030ce25f555737e8ba97bdd7883ac43f3ff2a3 Author: Damien Miller Date: Tue Feb 24 09:23:04 2015 -0800 include includes.h to avoid build failure on AIX commit 13af342458f5064144abbb07e5ac9bbd4eb42567 Author: Tim Rice Date: Tue Feb 24 07:56:47 2015 -0800 Original portability patch from djm@ for platforms missing err.h. Fix name space clash on Solaris 10. Still more to do for Solaris 10 to deal with msghdr structure differences. ok djm@ commit 910209203d0cd60c5083901cbcc0b7b44d9f48d2 Author: Tim Rice Date: Mon Feb 23 22:06:56 2015 -0800 cleaner way fix dispatch.h portion of commit a88dd1da119052870bb2654c1a32c51971eade16 (some systems have sig_atomic_t in signal.h, some in sys/signal.h) Sounds good to me djm@ commit 676c38d7cbe65b76bbfff796861bb6615cc6a596 Author: Tim Rice Date: Mon Feb 23 21:51:33 2015 -0800 portability fix: if we can't dind a better define for HOST_NAME_MAX, use 255 commit 1221b22023dce38cbc90ba77eae4c5d78c77a5e6 Author: Tim Rice Date: Mon Feb 23 21:50:34 2015 -0800 portablity fix: s/__inline__/inline/ commit 4c356308a88d309c796325bb75dce90ca16591d5 Author: Darren Tucker Date: Tue Feb 24 13:49:31 2015 +1100 Wrap stdint.h includes in HAVE_STDINT_H. commit c9c88355c6a27a908e7d1e5003a2b35ea99c1614 Author: Darren Tucker Date: Tue Feb 24 13:43:57 2015 +1100 Add AI_NUMERICSERV to fake-rfc2553. Our getaddrinfo implementation always returns numeric values already. commit ef342ab1ce6fb9a4b30186c89c309d0ae9d0eeb4 Author: Darren Tucker Date: Tue Feb 24 13:39:57 2015 +1100 Include OpenSSL's objects.h before bn.h. Prevents compile errors on some platforms (at least old GCCs and AIX's XLC compilers). commit dcc8997d116f615195aa7c9ec019fb36c28c6228 Author: Darren Tucker Date: Tue Feb 24 12:30:59 2015 +1100 Convert two macros into functions. Convert packet_send_debug and packet_disconnect from macros to functions. Some older GCCs (2.7.x, 2.95.x) see to have problems with variadic macros with only one argument so we convert these two into functions. ok djm@ commit 2285c30d51b7e2052c6526445abe7e7cc7e170a1 Author: djm@openbsd.org Date: Mon Feb 23 22:21:21 2015 +0000 upstream commit further silence spurious error message even when -v is specified (e.g. to get visual host keys); reported by naddy@ commit 9af21979c00652029e160295e988dea40758ece2 Author: Damien Miller Date: Tue Feb 24 09:04:32 2015 +1100 don't include stdint.h unless HAVE_STDINT_H set commit 62f678dd51660d6f8aee1da33d3222c5de10a89e Author: Damien Miller Date: Tue Feb 24 09:02:54 2015 +1100 nother sys/queue.h -> sys-queue.h fix spotted by Tom Christensen commit b3c19151cba2c0ed01b27f55de0d723ad07ca98f Author: djm@openbsd.org Date: Mon Feb 23 20:32:15 2015 +0000 upstream commit fix a race condition by using a mux socket rather than an ineffectual wait statement commit a88dd1da119052870bb2654c1a32c51971eade16 Author: Damien Miller Date: Tue Feb 24 06:30:29 2015 +1100 various include fixes for portable commit 5248429b5ec524d0a65507cff0cdd6e0cb99effd Author: djm@openbsd.org Date: Mon Feb 23 16:55:51 2015 +0000 upstream commit add an XXX to remind me to improve sshkey_load_public commit e94e4b07ef2eaead38b085a60535df9981cdbcdb Author: djm@openbsd.org Date: Mon Feb 23 16:55:31 2015 +0000 upstream commit silence a spurious error message when listing fingerprints for known_hosts; bz#2342 commit f2293a65392b54ac721f66bc0b44462e8d1d81f8 Author: djm@openbsd.org Date: Mon Feb 23 16:33:25 2015 +0000 upstream commit fix setting/clearing of TTY raw mode around UpdateHostKeys=ask confirmation question; reported by Herb Goldman commit f2004cd1adf34492eae0a44b1ef84e0e31b06088 Author: Darren Tucker Date: Mon Feb 23 05:04:21 2015 +1100 Repair for non-ECC OpenSSL. Ifdef out the ECC parts when building with an OpenSSL that doesn't have it. commit 37f9220db8d1a52c75894c3de1e5f2ae5bd71b6f Author: Darren Tucker Date: Mon Feb 23 03:07:24 2015 +1100 Wrap stdint.h includes in ifdefs. commit f81f1bbc5b892c8614ea740b1f92735652eb43f0 Author: Tim Rice Date: Sat Feb 21 18:12:10 2015 -0800 out of tree build fix commit 2e13a1e4d22f3b503c3bfc878562cc7386a1d1ae Author: Tim Rice Date: Sat Feb 21 18:08:51 2015 -0800 mkdir kex unit test directory so testing out of tree builds works commit 1797f49b1ba31e8700231cd6b1d512d80bb50d2c Author: halex@openbsd.org Date: Sat Feb 21 21:46:57 2015 +0000 upstream commit make "ssh-add -d" properly remove a corresponding certificate, and also not whine and fail if there is none ok djm@ commit 7faaa32da83a609059d95dbfcb0649fdb04caaf6 Author: Damien Miller Date: Sun Feb 22 07:57:27 2015 +1100 mkdir hostkey and bitmap unit test directories commit bd49da2ef197efac5e38f5399263a8b47990c538 Author: djm@openbsd.org Date: Fri Feb 20 23:46:01 2015 +0000 upstream commit sort options useable under Match case-insensitively; prodded jmc@ commit 1a779a0dd6cd8b4a1a40ea33b5415ab8408128ac Author: djm@openbsd.org Date: Sat Feb 21 20:51:02 2015 +0000 upstream commit correct paths to configuration files being written/updated; they live in $OBJ not cwd; some by Roumen Petrov commit 28ba006c1acddff992ae946d0bc0b500b531ba6b Author: Darren Tucker Date: Sat Feb 21 15:41:07 2015 +1100 More correct checking of HAVE_DECL_AI_NUMERICSERV. commit e50e8c97a9cecae1f28febccaa6ca5ab3bc10f54 Author: Darren Tucker Date: Sat Feb 21 15:10:33 2015 +1100 Add null declaration of AI_NUMERICINFO. Some platforms (older FreeBSD and DragonFly versions) do have getaddrinfo() but do not have AI_NUMERICINFO. so define it to zero in those cases. commit 18a208d6a460d707a45916db63a571e805f5db46 Author: djm@openbsd.org Date: Fri Feb 20 22:40:32 2015 +0000 upstream commit more options that are available under Match; bz#2353 reported by calestyo AT scientia.net commit 44732de06884238049f285f1455b2181baa7dc82 Author: djm@openbsd.org Date: Fri Feb 20 22:17:21 2015 +0000 upstream commit UpdateHostKeys fixes: I accidentally changed the format of the hostkeys@openssh.com messages last week without changing the extension name, and this has been causing connection failures for people who are running -current. First reported by sthen@ s/hostkeys@openssh.com/hostkeys-00@openssh.com/ Change the name of the proof message too, and reorder it a little. Also, UpdateHostKeys=ask is incompatible with ControlPersist (no TTY available to read the response) so disable UpdateHostKeys if it is in ask mode and ControlPersist is active (and document this) commit 13a39414d25646f93e6d355521d832a03aaaffe2 Author: djm@openbsd.org Date: Tue Feb 17 00:14:05 2015 +0000 upstream commit Regression: I broke logging of public key fingerprints in 1.46. Pointed out by Pontus Lundkvist commit 773dda25e828c4c9a52f7bdce6e1e5924157beab Author: Damien Miller Date: Fri Jan 30 23:10:17 2015 +1100 repair --without-openssl; broken in refactor commit e89c780886b23600de1e1c8d74aabd1ff61f43f0 Author: Damien Miller Date: Tue Feb 17 10:04:55 2015 +1100 hook up hostkeys unittest to portable Makefiles commit 0abf41f99aa16ff09b263bead242d6cb2dbbcf99 Author: djm@openbsd.org Date: Mon Feb 16 22:21:03 2015 +0000 upstream commit enable hostkeys unit tests commit 68a5d647ccf0fb6782b2f749433a1eee5bc9044b Author: djm@openbsd.org Date: Mon Feb 16 22:20:50 2015 +0000 upstream commit check string/memory compare arguments aren't NULL commit ef575ef20d09f20722e26b45dab80b3620469687 Author: djm@openbsd.org Date: Mon Feb 16 22:18:34 2015 +0000 upstream commit unit tests for hostfile.c code, just hostkeys_foreach so far commit 8ea3365e6aa2759ccf5c76eaea62cbc8a280b0e7 Author: markus@openbsd.org Date: Sat Feb 14 12:43:16 2015 +0000 upstream commit test server rekey limit commit ce63c4b063c39b2b22d4ada449c9e3fbde788cb3 Author: djm@openbsd.org Date: Mon Feb 16 22:30:03 2015 +0000 upstream commit partial backout of: revision 1.441 date: 2015/01/31 20:30:05; author: djm; state: Exp; lines: +17 -10; commitid : x8klYPZMJSrVlt3O; Let sshd load public host keys even when private keys are missing. Allows sshd to advertise additional keys for future key rotation. Also log fingerprint of hostkeys loaded; ok markus@ hostkey updates now require access to the private key, so we can't load public keys only. The improved log messages (fingerprints of keys loaded) are kept. commit 523463a3a2a9bfc6cfc5afa01bae9147f76a37cc Author: djm@openbsd.org Date: Mon Feb 16 22:13:32 2015 +0000 upstream commit Revise hostkeys@openssh.com hostkey learning extension. The client will not ask the server to prove ownership of the private halves of any hitherto-unseen hostkeys it offers to the client. Allow UpdateHostKeys option to take an 'ask' argument to let the user manually review keys offered. ok markus@ commit 6c5c949782d86a6e7d58006599c7685bfcd01685 Author: djm@openbsd.org Date: Mon Feb 16 22:08:57 2015 +0000 upstream commit Refactor hostkeys_foreach() and dependent code Deal with IP addresses (i.e. CheckHostIP) Don't clobber known_hosts when nothing changed ok markus@ as part of larger commit commit 51b082ccbe633dc970df1d1f4c9c0497115fe721 Author: miod@openbsd.org Date: Mon Feb 16 18:26:26 2015 +0000 upstream commit Declare ge25519_base as extern, to prevent it from becoming a common. Gets us rid of ``lignment 4 of symbol `crypto_sign_ed25519_ref_ge25519_base' in mod_ge25519.o is smaller than 16 in mod_ed25519.o'' warnings at link time. commit 02db468bf7e3281a8e3c058ced571b38b6407c34 Author: markus@openbsd.org Date: Fri Feb 13 18:57:00 2015 +0000 upstream commit make rekey_limit for sshd w/privsep work; ok djm@ dtucker@ commit 8ec67d505bd23c8bf9e17b7a364b563a07a58ec8 Author: dtucker@openbsd.org Date: Thu Feb 12 20:34:19 2015 +0000 upstream commit Prevent sshd spamming syslog with "ssh_dispatch_run_fatal: disconnected". ok markus@ commit d4c0295d1afc342057ba358237acad6be8af480b Author: djm@openbsd.org Date: Wed Feb 11 01:20:38 2015 +0000 upstream commit Some packet error messages show the address of the peer, but might be generated after the socket to the peer has suffered a TCP reset. In these cases, getpeername() won't work so cache the address earlier. spotted in the wild via deraadt@ and tedu@ commit 4af1709cf774475ce5d1bc3ddcc165f6c222897d Author: jsg@openbsd.org Date: Mon Feb 9 23:22:37 2015 +0000 upstream commit fix some leaks in error paths ok markus@ commit fd36834871d06a03e1ff8d69e41992efa1bbf85f Author: millert@openbsd.org Date: Fri Feb 6 23:21:59 2015 +0000 upstream commit SIZE_MAX is standard, we should be using it in preference to the obsolete SIZE_T_MAX. OK miod@ beck@ commit 1910a286d7771eab84c0b047f31c0a17505236fa Author: millert@openbsd.org Date: Thu Feb 5 12:59:57 2015 +0000 upstream commit Include stdint.h, not limits.h to get SIZE_MAX. OK guenther@ commit ce4f59b2405845584f45e0b3214760eb0008c06c Author: deraadt@openbsd.org Date: Tue Feb 3 08:07:20 2015 +0000 upstream commit missing ; djm and mlarkin really having great interactions recently commit 5d34aa94938abb12b877a25be51862757f25d54b Author: halex@openbsd.org Date: Tue Feb 3 00:34:14 2015 +0000 upstream commit slightly extend the passphrase prompt if running with -c in order to give the user a chance to notice if unintentionally running without it wording tweak and ok djm@ commit cb3bde373e80902c7d5d0db429f85068d19b2918 Author: djm@openbsd.org Date: Mon Feb 2 22:48:53 2015 +0000 upstream commit handle PKCS#11 C_Login returning CKR_USER_ALREADY_LOGGED_IN; based on patch from Yuri Samoilenko; ok markus@ commit 15ad750e5ec3cc69765b7eba1ce90060e7083399 Author: djm@openbsd.org Date: Mon Feb 2 07:41:40 2015 +0000 upstream commit turn UpdateHostkeys off by default until I figure out mlarkin@'s warning message; requested by deraadt@ commit 3cd5103c1e1aaa59bd66f7f52f6ebbcd5deb12f9 Author: deraadt@openbsd.org Date: Mon Feb 2 01:57:44 2015 +0000 upstream commit increasing encounters with difficult DNS setups in darknets has convinced me UseDNS off by default is better ok djm commit 6049a548a8a68ff0bbe581ab1748ea6a59ecdc38 Author: djm@openbsd.org Date: Sat Jan 31 20:30:05 2015 +0000 upstream commit Let sshd load public host keys even when private keys are missing. Allows sshd to advertise additional keys for future key rotation. Also log fingerprint of hostkeys loaded; ok markus@ commit 46347ed5968f582661e8a70a45f448e0179ca0ab Author: djm@openbsd.org Date: Fri Jan 30 11:43:14 2015 +0000 upstream commit Add a ssh_config HostbasedKeyType option to control which host public key types are tried during hostbased authentication. This may be used to prevent too many keys being sent to the server, and blowing past its MaxAuthTries limit. bz#2211 based on patch by Iain Morgan; ok markus@ commit 802660cb70453fa4d230cb0233bc1bbdf8328de1 Author: djm@openbsd.org Date: Fri Jan 30 10:44:49 2015 +0000 upstream commit set a timeout to prevent hangs when talking to busted servers; ok markus@ commit 86936ec245a15c7abe71a0722610998b0a28b194 Author: djm@openbsd.org Date: Fri Jan 30 01:11:39 2015 +0000 upstream commit regression test for 'wildcard CA' serial/key ID revocations commit 4509b5d4a4fa645a022635bfa7e86d09b285001f Author: djm@openbsd.org Date: Fri Jan 30 01:13:33 2015 +0000 upstream commit avoid more fatal/exit in the packet.c paths that ssh-keyscan uses; feedback and "looks good" markus@ commit 669aee994348468af8b4b2ebd29b602cf2860b22 Author: djm@openbsd.org Date: Fri Jan 30 01:10:33 2015 +0000 upstream commit permit KRLs that revoke certificates by serial number or key ID without scoping to a particular CA; ok markus@ commit 7a2c368477e26575d0866247d3313da4256cb2b5 Author: djm@openbsd.org Date: Fri Jan 30 00:59:19 2015 +0000 upstream commit missing parentheses after if in do_convert_from() broke private key conversion from other formats some time in 2010; bz#2345 reported by jjelen AT redhat.com commit 25f5f78d8bf5c22d9cea8b49de24ebeee648a355 Author: djm@openbsd.org Date: Fri Jan 30 00:22:25 2015 +0000 upstream commit fix ssh protocol 1, spotted by miod@ commit 9ce86c926dfa6e0635161b035e3944e611cbccf0 Author: djm@openbsd.org Date: Wed Jan 28 22:36:00 2015 +0000 upstream commit update to new API (key_fingerprint => sshkey_fingerprint) check sshkey_fingerprint return values; ok markus commit 9125525c37bf73ad3ee4025520889d2ce9d10f29 Author: djm@openbsd.org Date: Wed Jan 28 22:05:31 2015 +0000 upstream commit avoid fatal() calls in packet code makes ssh-keyscan more reliable against server failures ok dtucker@ markus@ commit fae7bbe544cba7a9e5e4ab47ff6faa3d978646eb Author: djm@openbsd.org Date: Wed Jan 28 21:15:47 2015 +0000 upstream commit avoid fatal() calls in packet code makes ssh-keyscan more reliable against server failures ok dtucker@ markus@ commit 1a3d14f6b44a494037c7deab485abe6496bf2c60 Author: djm@openbsd.org Date: Wed Jan 28 11:07:25 2015 +0000 upstream commit remove obsolete comment commit 80c25b7bc0a71d75c43a4575d9a1336f589eb639 Author: okan@openbsd.org Date: Tue Jan 27 12:54:06 2015 +0000 upstream commit Since r1.2 removed the use of PRI* macros, inttypes.h is no longer required. ok djm@ commit 69ff64f69615c2a21c97cb5878a0996c21423257 Author: Damien Miller Date: Tue Jan 27 23:07:43 2015 +1100 compile on systems without TCP_MD5SIG (e.g. OSX) commit 358964f3082fb90b2ae15bcab07b6105cfad5a43 Author: Damien Miller Date: Tue Jan 27 23:07:25 2015 +1100 use ssh-keygen under test rather than system's commit a2c95c1bf33ea53038324d1fdd774bc953f98236 Author: Damien Miller Date: Tue Jan 27 23:06:59 2015 +1100 OSX lacks HOST_NAME_MAX, has _POSIX_HOST_NAME_MAX commit ade31d7b6f608a19b85bee29a7a00b1e636a2919 Author: Damien Miller Date: Tue Jan 27 23:06:23 2015 +1100 these need active_state defined to link on OSX temporary measure until active_state goes away entirely commit e56aa87502f22c5844918c10190e8b4f785f067b Author: djm@openbsd.org Date: Tue Jan 27 12:01:36 2015 +0000 upstream commit use printf instead of echo -n to reduce diff against -portable commit 9f7637f56eddfaf62ce3c0af89c25480f2cf1068 Author: jmc@openbsd.org Date: Mon Jan 26 13:55:29 2015 +0000 upstream commit sort previous; commit 3076ee7d530d5b16842fac7a6229706c7e5acd26 Author: djm@openbsd.org Date: Mon Jan 26 13:36:53 2015 +0000 upstream commit properly restore umask commit d411d395556b73ba1b9e451516a0bd6697c4b03d Author: djm@openbsd.org Date: Mon Jan 26 06:12:18 2015 +0000 upstream commit regression test for host key rotation commit fe8a3a51699afbc6407a8fae59b73349d01e49f8 Author: djm@openbsd.org Date: Mon Jan 26 06:11:28 2015 +0000 upstream commit adapt to sshkey API tweaks commit 7dd355fb1f0038a3d5cdca57ebab4356c7a5b434 Author: miod@openbsd.org Date: Sat Jan 24 10:39:21 2015 +0000 upstream commit Move -lz late in the linker commandline for things to build on static arches. commit 0dad3b806fddb93c475b30853b9be1a25d673a33 Author: miod@openbsd.org Date: Fri Jan 23 21:21:23 2015 +0000 upstream commit -Wpointer-sign is supported by gcc 4 only. commit 2b3b1c1e4bd9577b6e780c255c278542ea66c098 Author: djm@openbsd.org Date: Tue Jan 20 22:58:57 2015 +0000 upstream commit use SUBDIR to recuse into unit tests; makes "make obj" actually work commit 1d1092bff8db27080155541212b420703f8b9c92 Author: djm@openbsd.org Date: Mon Jan 26 12:16:36 2015 +0000 upstream commit correct description of UpdateHostKeys in ssh_config.5 and add it to -o lists for ssh, scp and sftp; pointed out by jmc@ commit 5104db7cbd6cdd9c5971f4358e74414862fc1022 Author: djm@openbsd.org Date: Mon Jan 26 06:10:03 2015 +0000 upstream commit correctly match ECDSA subtype (== curve) for offered/recevied host keys. Fixes connection-killing host key mismatches when a server offers multiple ECDSA keys with different curve type (an extremely unlikely configuration). ok markus, "looks mechanical" deraadt@ commit 8d4f87258f31cb6def9b3b55b6a7321d84728ff2 Author: djm@openbsd.org Date: Mon Jan 26 03:04:45 2015 +0000 upstream commit Host key rotation support. Add a hostkeys@openssh.com protocol extension (global request) for a server to inform a client of all its available host key after authentication has completed. The client may record the keys in known_hosts, allowing it to upgrade to better host key algorithms and a server to gracefully rotate its keys. The client side of this is controlled by a UpdateHostkeys config option (default on). ok markus@ commit 60b1825262b1f1e24fc72050b907189c92daf18e Author: djm@openbsd.org Date: Mon Jan 26 02:59:11 2015 +0000 upstream commit small refactor and add some convenience functions; ok markus commit a5a3e3328ddce91e76f71ff479022d53e35c60c9 Author: jmc@openbsd.org Date: Thu Jan 22 21:00:42 2015 +0000 upstream commit heirarchy -> hierarchy; commit dcff5810a11195c57e1b3343c0d6b6f2b9974c11 Author: deraadt@openbsd.org Date: Thu Jan 22 20:24:41 2015 +0000 upstream commit Provide a warning about chroot misuses (which sadly, seem to have become quite popular because shiny). sshd cannot detect/manage/do anything about these cases, best we can do is warn in the right spot in the man page. ok markus commit 087266ec33c76fc8d54ac5a19efacf2f4a4ca076 Author: deraadt@openbsd.org Date: Tue Jan 20 23:14:00 2015 +0000 upstream commit Reduce use of and transition to throughout. ok djm markus commit 57e783c8ba2c0797f93977e83b2a8644a03065d8 Author: markus@openbsd.org Date: Tue Jan 20 20:16:21 2015 +0000 upstream commit kex_setup errors are fatal() commit 1d6424a6ff94633c221297ae8f42d54e12a20912 Author: djm@openbsd.org Date: Tue Jan 20 08:02:33 2015 +0000 upstream commit this test would accidentally delete agent.sh if run without obj/ commit 12b5f50777203e12575f1b08568281e447249ed3 Author: djm@openbsd.org Date: Tue Jan 20 07:56:44 2015 +0000 upstream commit make this compile with KERBEROS5 enabled commit e2cc6bef08941256817d44d146115b3478586ad4 Author: djm@openbsd.org Date: Tue Jan 20 07:55:33 2015 +0000 upstream commit fix hostkeys in agent; ok markus@ commit 1ca3e2155aa5d3801a7ae050f85c71f41fcb95b1 Author: Damien Miller Date: Tue Jan 20 10:11:31 2015 +1100 fix kex test commit c78a578107c7e6dcf5d30a2f34cb6581bef14029 Author: markus@openbsd.org Date: Mon Jan 19 20:45:25 2015 +0000 upstream commit finally enable the KEX tests I wrote some years ago... commit 31821d7217e686667d04935aeec99e1fc4a46e7e Author: markus@openbsd.org Date: Mon Jan 19 20:42:31 2015 +0000 upstream commit adapt to new error message (SSH_ERR_MAC_INVALID) commit d3716ca19e510e95d956ae14d5b367e364bff7f1 Author: djm@openbsd.org Date: Mon Jan 19 17:31:13 2015 +0000 upstream commit this test was broken in at least two ways, such that it wasn't checking that a KRL was not excluding valid keys commit 3f797653748e7c2b037dacb57574c01d9ef3b4d3 Author: markus@openbsd.org Date: Mon Jan 19 20:32:39 2015 +0000 upstream commit switch ssh-keyscan from setjmp to multiple ssh transport layer instances ok djm@ commit f582f0e917bb0017b00944783cd5f408bf4b0b5e Author: markus@openbsd.org Date: Mon Jan 19 20:30:23 2015 +0000 upstream commit add experimental api for packet layer; ok djm@ commit 48b3b2ba75181f11fca7f327058a591f4426cade Author: markus@openbsd.org Date: Mon Jan 19 20:20:20 2015 +0000 upstream commit store compat flags in struct ssh; ok djm@ commit 57d10cbe861a235dd269c74fb2fe248469ecee9d Author: markus@openbsd.org Date: Mon Jan 19 20:16:15 2015 +0000 upstream commit adapt kex to sshbuf and struct ssh; ok djm@ commit 3fdc88a0def4f86aa88a5846ac079dc964c0546a Author: markus@openbsd.org Date: Mon Jan 19 20:07:45 2015 +0000 upstream commit move dispatch to struct ssh; ok djm@ commit 091c302829210c41e7f57c3f094c7b9c054306f0 Author: markus@openbsd.org Date: Mon Jan 19 19:52:16 2015 +0000 upstream commit update packet.c & isolate, introduce struct ssh a) switch packet.c to buffer api and isolate per-connection info into struct ssh b) (de)serialization of the state is moved from monitor to packet.c c) the old packet.c API is implemented in opacket.[ch] d) compress.c/h is removed and integrated into packet.c with and ok djm@ commit 4e62cc68ce4ba20245d208b252e74e91d3785b74 Author: djm@openbsd.org Date: Mon Jan 19 17:35:48 2015 +0000 upstream commit fix format strings in (disabled) debugging commit d85e06245907d49a2cd0cfa0abf59150ad616f42 Author: djm@openbsd.org Date: Mon Jan 19 06:01:32 2015 +0000 upstream commit be a bit more careful in these tests to ensure that known_hosts is clean commit 7947810eab5fe0ad311f32a48f4d4eb1f71be6cf Author: djm@openbsd.org Date: Sun Jan 18 22:00:18 2015 +0000 upstream commit regression test for known_host file editing using ssh-keygen (-H / -R / -F) after hostkeys_foreach() change; feedback and ok markus@ commit 3a2b09d147a565d8a47edf37491e149a02c0d3a3 Author: djm@openbsd.org Date: Sun Jan 18 19:54:46 2015 +0000 upstream commit more and better key tests test signatures and verification test certificate generation flesh out nested cert test removes most of the XXX todo markers commit 589e69fd82724cfc9738f128e4771da2e6405d0d Author: djm@openbsd.org Date: Sun Jan 18 19:53:58 2015 +0000 upstream commit make the signature fuzzing test much more rigorous: ensure that the fuzzed input cases do not match the original (using new fuzz_matches_original() function) and check that the verification fails in each case commit 80603c0daa2538c349c1c152405580b164d5475f Author: djm@openbsd.org Date: Sun Jan 18 19:52:44 2015 +0000 upstream commit add a fuzz_matches_original() function to the fuzzer to detect fuzz cases that are identical to the original data. Hacky implementation, but very useful when you need the fuzz to be different, e.g. when verifying signature commit 87d5495bd337e358ad69c524fcb9495208c0750b Author: djm@openbsd.org Date: Sun Jan 18 19:50:55 2015 +0000 upstream commit better dumps from the fuzzer (shown on errors) - include the original data as well as the fuzzed copy. commit d59ec478c453a3fff05badbbfd96aa856364f2c2 Author: djm@openbsd.org Date: Sun Jan 18 19:47:55 2015 +0000 upstream commit enable hostkey-agent.sh test commit 26b3425170bf840e4b095e1c10bf25a0a3e3a105 Author: djm@openbsd.org Date: Sat Jan 17 18:54:30 2015 +0000 upstream commit unit test for hostkeys in ssh-agent commit 9e06a0fb23ec55d9223b26a45bb63c7649e2f2f2 Author: markus@openbsd.org Date: Thu Jan 15 23:41:29 2015 +0000 upstream commit add kex unit tests commit d2099dec6da21ae627f6289aedae6bc1d41a22ce Author: deraadt@openbsd.org Date: Mon Jan 19 00:32:54 2015 +0000 upstream commit djm, your /usr/include tree is old commit 2b3c3c76c30dc5076fe09d590f5b26880f148a54 Author: djm@openbsd.org Date: Sun Jan 18 21:51:19 2015 +0000 upstream commit some feedback from markus@: comment hostkeys_foreach() context and avoid a member in it. commit cecb30bc2ba6d594366e657d664d5c494b6c8a7f Author: djm@openbsd.org Date: Sun Jan 18 21:49:42 2015 +0000 upstream commit make ssh-keygen use hostkeys_foreach(). Removes some horrendous code; ok markus@ commit ec3d065df3a9557ea96b02d061fd821a18c1a0b9 Author: djm@openbsd.org Date: Sun Jan 18 21:48:09 2015 +0000 upstream commit convert load_hostkeys() (hostkey ordering and known_host matching) to use the new hostkey_foreach() iterator; ok markus commit c29811cc480a260e42fd88849fc86a80c1e91038 Author: djm@openbsd.org Date: Sun Jan 18 21:40:23 2015 +0000 upstream commit introduce hostkeys_foreach() to allow iteration over a known_hosts file or controlled subset thereof. This will allow us to pull out some ugly and duplicated code, and will be used to implement hostkey rotation later. feedback and ok markus commit f101d8291da01bbbfd6fb8c569cfd0cc61c0d346 Author: deraadt@openbsd.org Date: Sun Jan 18 14:01:00 2015 +0000 upstream commit string truncation due to sizeof(size) ok djm markus commit 35d6022b55b7969fc10c261cb6aa78cc4a5fcc41 Author: djm@openbsd.org Date: Sun Jan 18 13:33:34 2015 +0000 upstream commit avoid trailing ',' in host key algorithms commit 7efb455789a0cb76bdcdee91c6060a3dc8f5c007 Author: djm@openbsd.org Date: Sun Jan 18 13:22:28 2015 +0000 upstream commit infer key length correctly when user specified a fully- qualified key name instead of using the -b bits option; ok markus@ commit 83f8ffa6a55ccd0ce9d8a205e3e7439ec18fedf5 Author: djm@openbsd.org Date: Sat Jan 17 18:53:34 2015 +0000 upstream commit fix hostkeys on ssh agent; found by unit test I'm about to commit commit 369d61f17657b814124268f99c033e4dc6e436c1 Author: schwarze@openbsd.org Date: Fri Jan 16 16:20:23 2015 +0000 upstream commit garbage collect empty .No macros mandoc warns about commit bb8b442d32dbdb8521d610e10d8b248d938bd747 Author: djm@openbsd.org Date: Fri Jan 16 15:55:07 2015 +0000 upstream commit regression: incorrect error message on otherwise-successful ssh-keygen -A. Reported by Dmitry Orlov, via deraadt@ commit 9010902954a40b59d0bf3df3ccbc3140a653e2bc Author: djm@openbsd.org Date: Fri Jan 16 07:19:48 2015 +0000 upstream commit when hostname canonicalisation is enabled, try to parse hostnames as addresses before looking them up for canonicalisation. fixes bz#2074 and avoids needless DNS lookups in some cases; ok markus commit 2ae4f337b2a5fb2841b6b0053b49496fef844d1c Author: deraadt@openbsd.org Date: Fri Jan 16 06:40:12 2015 +0000 upstream commit Replace with and other less dirty headers where possible. Annotate lines with their current reasons. Switch to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where sensible to avoid pulling in the pollution. These are the files confirmed through binary verification. ok guenther, millert, doug (helped with the verification protocol) commit 3c4726f4c24118e8f1bb80bf75f1456c76df072c Author: markus@openbsd.org Date: Thu Jan 15 21:38:50 2015 +0000 upstream commit remove xmalloc, switch to sshbuf commit e17ac01f8b763e4b83976b9e521e90a280acc097 Author: markus@openbsd.org Date: Thu Jan 15 21:37:14 2015 +0000 upstream commit switch to sshbuf commit ddef9995a1fa6c7a8ff3b38bfe6cf724bebf13d0 Author: naddy@openbsd.org Date: Thu Jan 15 18:32:54 2015 +0000 upstream commit handle UMAC128 initialization like UMAC; ok djm@ markus@ commit f14564c1f7792446bca143580aef0e7ac25dcdae Author: djm@openbsd.org Date: Thu Jan 15 11:04:36 2015 +0000 upstream commit fix regression reported by brad@ for passworded keys without agent present commit 45c0fd70bb2a88061319dfff20cb12ef7b1bc47e Author: Damien Miller Date: Thu Jan 15 22:08:23 2015 +1100 make bitmap test compile commit d333f89abf7179021e5c3f28673f469abe032062 Author: djm@openbsd.org Date: Thu Jan 15 07:36:28 2015 +0000 upstream commit unit tests for KRL bitmap commit 7613f828f49c55ff356007ae9645038ab6682556 Author: markus@openbsd.org Date: Wed Jan 14 09:58:21 2015 +0000 upstream commit re-add comment about full path commit 6c43b48b307c41cd656b415621a644074579a578 Author: markus@openbsd.org Date: Wed Jan 14 09:54:38 2015 +0000 upstream commit don't reset to the installed sshd; connect before reconfigure, too commit 771bb47a1df8b69061f09462e78aa0b66cd594bf Author: djm@openbsd.org Date: Tue Jan 13 14:51:51 2015 +0000 upstream commit implement a SIGINFO handler so we can discern a stuck fuzz test from a merely glacial one; prompted by and ok markus commit cfaa57962f8536f3cf0fd7daf4d6a55d6f6de45f Author: djm@openbsd.org Date: Tue Jan 13 08:23:26 2015 +0000 upstream commit use $SSH instead of installed ssh to allow override; spotted by markus@ commit 0920553d0aee117a596b03ed5b49b280d34a32c5 Author: djm@openbsd.org Date: Tue Jan 13 07:49:49 2015 +0000 upstream commit regress test for PubkeyAcceptedKeyTypes; ok markus@ commit 27ca1a5c0095eda151934bca39a77e391f875d17 Author: markus@openbsd.org Date: Mon Jan 12 20:13:27 2015 +0000 upstream commit unbreak parsing of pubkey comments; with gerhard; ok djm/deraadt commit 55358f0b4e0b83bc0df81c5f854c91b11e0bb4dc Author: djm@openbsd.org Date: Mon Jan 12 11:46:32 2015 +0000 upstream commit fatal if soft-PKCS11 library is missing rather (rather than continue and fail with a more cryptic error) commit c3554cdd2a1a62434b8161017aa76fa09718a003 Author: djm@openbsd.org Date: Mon Jan 12 11:12:38 2015 +0000 upstream commit let this test all supporte key types; pointed out/ok markus@ commit 1129dcfc5a3e508635004bcc05a3574cb7687167 Author: djm@openbsd.org Date: Thu Jan 15 09:40:00 2015 +0000 upstream commit sync ssh-keysign, ssh-keygen and some dependencies to the new buffer/key API; mostly mechanical, ok markus@ commit e4ebf5586452bf512da662ac277aaf6ecf0efe7c Author: djm@openbsd.org Date: Thu Jan 15 07:57:08 2015 +0000 upstream commit remove commented-out test code now that it has moved to a proper unit test commit e81cba066c1e9eb70aba0f6e7c0ff220611b370f Author: djm@openbsd.org Date: Wed Jan 14 20:54:29 2015 +0000 upstream commit whitespace commit 141efe49542f7156cdbc2e4cd0a041d8b1aab622 Author: djm@openbsd.org Date: Wed Jan 14 20:05:27 2015 +0000 upstream commit move authfd.c and its tentacles to the new buffer/key API; ok markus@ commit 0088c57af302cda278bd26d8c3ae81d5b6f7c289 Author: djm@openbsd.org Date: Wed Jan 14 19:33:41 2015 +0000 upstream commit fix small regression: ssh-agent would return a success message but an empty signature if asked to sign using an unknown key; ok markus@ commit b03ebe2c22b8166e4f64c37737f4278676e3488d Author: Damien Miller Date: Thu Jan 15 03:08:58 2015 +1100 more --without-openssl fix some regressions caused by upstream merges enable KRLs now that they no longer require BIGNUMs commit bc42cc6fe784f36df225c44c93b74830027cb5a2 Author: Damien Miller Date: Thu Jan 15 03:08:29 2015 +1100 kludge around tun API mismatch betterer commit c332110291089b624fa0951fbf2d1ee6de525b9f Author: Damien Miller Date: Thu Jan 15 02:59:51 2015 +1100 some systems lack SO_REUSEPORT commit 83b9678a62cbdc74eb2031cf1e1e4ffd58e233ae Author: Damien Miller Date: Thu Jan 15 02:35:50 2015 +1100 fix merge botch commit 0cdc5a3eb6fb383569a4da2a30705d9b90428d6b Author: Damien Miller Date: Thu Jan 15 02:35:33 2015 +1100 unbreak across API change commit 6e2549ac2b5e7f96cbc2d83a6e0784b120444b47 Author: Damien Miller Date: Thu Jan 15 02:30:18 2015 +1100 need includes.h for portable OpenSSH commit 72ef7c148c42db7d5632a29f137f8b87b579f2d9 Author: Damien Miller Date: Thu Jan 15 02:21:31 2015 +1100 support --without-openssl at configure time Disables and removes dependency on OpenSSL. Many features don't work and the set of crypto options is greatly restricted. This will only work on system with native arc4random or /dev/urandom. Considered highly experimental for now. commit 4f38c61c68ae7e3f9ee4b3c38bc86cd39f65ece9 Author: Damien Miller Date: Thu Jan 15 02:28:00 2015 +1100 add files missed in last commit commit a165bab605f7be55940bb8fae977398e8c96a46d Author: djm@openbsd.org Date: Wed Jan 14 15:02:39 2015 +0000 upstream commit avoid BIGNUM in KRL code by using a simple bitmap; feedback and ok markus commit 7d845f4a0b7ec97887be204c3760e44de8bf1f32 Author: djm@openbsd.org Date: Wed Jan 14 13:54:13 2015 +0000 upstream commit update sftp client and server to new buffer API. pretty much just mechanical changes; with & ok markus commit 139ca81866ec1b219c717d17061e5e7ad1059e2a Author: markus@openbsd.org Date: Wed Jan 14 13:09:09 2015 +0000 upstream commit switch to sshbuf/sshkey; with & ok djm@ commit 81bfbd0bd35683de5d7f2238b985e5f8150a9180 Author: Damien Miller Date: Wed Jan 14 21:48:18 2015 +1100 support --without-openssl at configure time Disables and removes dependency on OpenSSL. Many features don't work and the set of crypto options is greatly restricted. This will only work on system with native arc4random or /dev/urandom. Considered highly experimental for now. commit 54924b53af15ccdcbb9f89984512b5efef641a31 Author: djm@openbsd.org Date: Wed Jan 14 10:46:28 2015 +0000 upstream commit avoid an warning for the !OPENSSL case commit ae8b463217f7c9b66655bfc3945c050ffdaeb861 Author: markus@openbsd.org Date: Wed Jan 14 10:30:34 2015 +0000 upstream commit swith auth-options to new sshbuf/sshkey; ok djm@ commit 540e891191b98b89ee90aacf5b14a4a68635e763 Author: djm@openbsd.org Date: Wed Jan 14 10:29:45 2015 +0000 upstream commit make non-OpenSSL aes-ctr work on sshd w/ privsep; ok markus@ commit 60c2c4ea5e1ad0ddfe8b2877b78ed5143be79c53 Author: markus@openbsd.org Date: Wed Jan 14 10:24:42 2015 +0000 upstream commit remove unneeded includes, sync my copyright across files & whitespace; ok djm@ commit 128343bcdb0b60fc826f2733df8cf979ec1627b4 Author: markus@openbsd.org Date: Tue Jan 13 19:31:40 2015 +0000 upstream commit adapt mac.c to ssherr.h return codes (de-fatal) and simplify dependencies ok djm@ commit e7fd952f4ea01f09ceb068721a5431ac2fd416ed Author: djm@openbsd.org Date: Tue Jan 13 19:04:35 2015 +0000 upstream commit sync changes from libopenssh; prepared by markus@ mostly debug output tweaks, a couple of error return value changes and some other minor stuff commit 76c0480a85675f03a1376167cb686abed01a3583 Author: Damien Miller Date: Tue Jan 13 19:38:18 2015 +1100 add --without-ssh1 option to configure Allows disabling support for SSH protocol 1. commit 1f729f0614d1376c3332fa1edb6a5e5cec7e9e03 Author: djm@openbsd.org Date: Tue Jan 13 07:39:19 2015 +0000 upstream commit add sshd_config HostbasedAcceptedKeyTypes and PubkeyAcceptedKeyTypes options to allow sshd to control what public key types will be accepted. Currently defaults to all. Feedback & ok markus@ commit 816d1538c24209a93ba0560b27c4fda57c3fff65 Author: markus@openbsd.org Date: Mon Jan 12 20:13:27 2015 +0000 upstream commit unbreak parsing of pubkey comments; with gerhard; ok djm/deraadt commit 0097565f849851812df610b7b6b3c4bd414f6c62 Author: markus@openbsd.org Date: Mon Jan 12 19:22:46 2015 +0000 upstream commit missing error assigment on sshbuf_put_string() commit a7f49dcb527dd17877fcb8d5c3a9a6f550e0bba5 Author: djm@openbsd.org Date: Mon Jan 12 15:18:07 2015 +0000 upstream commit apparently memcpy(x, NULL, 0) is undefined behaviour according to C99 (cf. sections 7.21.1 and 7.1.4), so check skip memcpy calls when length==0; ok markus@ commit 905fe30fca82f38213763616d0d26eb6790bde33 Author: markus@openbsd.org Date: Mon Jan 12 14:05:19 2015 +0000 upstream commit free->sshkey_free; ok djm@ commit f067cca2bc20c86b110174c3fef04086a7f57b13 Author: markus@openbsd.org Date: Mon Jan 12 13:29:27 2015 +0000 upstream commit allow WITH_OPENSSL w/o WITH_SSH1; ok djm@ commit c4bfafcc2a9300d9cfb3c15e75572d3a7d74670d Author: djm@openbsd.org Date: Thu Jan 8 13:10:58 2015 +0000 upstream commit adjust for sshkey_load_file() API change commit e752c6d547036c602b89e9e704851463bd160e32 Author: djm@openbsd.org Date: Thu Jan 8 13:44:36 2015 +0000 upstream commit fix ssh_config FingerprintHash evaluation order; from Petr Lautrbach commit ab24ab847b0fc94c8d5e419feecff0bcb6d6d1bf Author: djm@openbsd.org Date: Thu Jan 8 10:15:45 2015 +0000 upstream commit reorder hostbased key attempts to better match the default hostkey algorithms order in myproposal.h; ok markus@ commit 1195f4cb07ef4b0405c839293c38600b3e9bdb46 Author: djm@openbsd.org Date: Thu Jan 8 10:14:08 2015 +0000 upstream commit deprecate key_load_private_pem() and sshkey_load_private_pem() interfaces. Refactor the generic key loading API to not require pathnames to be specified (they weren't really used). Fixes a few other things en passant: Makes ed25519 keys work for hostbased authentication (ssh-keysign previously used the PEM-only routines). Fixes key comment regression bz#2306: key pathnames were being lost as comment fields. ok markus@ commit febbe09e4e9aff579b0c5cc1623f756862e4757d Author: tedu@openbsd.org Date: Wed Jan 7 18:15:07 2015 +0000 upstream commit workaround for the Meyer, et al, Bleichenbacher Side Channel Attack. fake up a bignum key before RSA decryption. discussed/ok djm markus commit 5191df927db282d3123ca2f34a04d8d96153911a Author: djm@openbsd.org Date: Tue Dec 23 22:42:48 2014 +0000 upstream commit KNF and add a little more debug() commit 8abd80315d3419b20e6938f74d37e2e2b547f0b7 Author: jmc@openbsd.org Date: Mon Dec 22 09:26:31 2014 +0000 upstream commit add fingerprinthash to the options list; commit 296ef0560f60980da01d83b9f0e1a5257826536f Author: jmc@openbsd.org Date: Mon Dec 22 09:24:59 2014 +0000 upstream commit tweak previous; commit 462082eacbd37778a173afb6b84c6f4d898a18b5 Author: Damien Miller Date: Tue Dec 30 08:16:11 2014 +1100 avoid uninitialised free of ldns_res If an invalid rdclass was passed to getrrsetbyname() then this would execute a free on an uninitialised pointer. OpenSSH only ever calls this with a fixed and valid rdclass. Reported by Joshua Rogers commit 01b63498801053f131a0740eb9d13faf35d636c8 Author: Damien Miller Date: Mon Dec 29 18:10:18 2014 +1100 pull updated OpenBSD BCrypt PBKDF implementation Includes fix for 1 byte output overflow for large key length requests (not reachable in OpenSSH). Pointed out by Joshua Rogers commit c528c1b4af2f06712177b3de9b30705752f7cbcb Author: Damien Miller Date: Tue Dec 23 15:26:13 2014 +1100 fix variable name for IPv6 case in construct_utmpx patch from writeonce AT midipix.org via bz#2296 commit 293cac52dcda123244b2e594d15592e5e481c55e Author: Damien Miller Date: Mon Dec 22 16:30:42 2014 +1100 include and use OpenBSD netcat in regress/ commit 8f6784f0cb56dc4fd00af3e81a10050a5785228d Author: djm@openbsd.org Date: Mon Dec 22 09:05:17 2014 +0000 upstream commit mention ssh -Q feature to list supported { MAC, cipher, KEX, key } algorithms in more places and include the query string used to list the relevant information; bz#2288 commit 449e11b4d7847079bd0a2daa6e3e7ea03d8ef700 Author: jmc@openbsd.org Date: Mon Dec 22 08:24:17 2014 +0000 upstream commit tweak previous; commit 4bea0ab3290c0b9dd2aa199e932de8e7e18062d6 Author: djm@openbsd.org Date: Mon Dec 22 08:06:03 2014 +0000 upstream commit regression test for multiple required pubkey authentication; ok markus@ commit f1c4d8ec52158b6f57834b8cd839605b0a33e7f2 Author: djm@openbsd.org Date: Mon Dec 22 08:04:23 2014 +0000 upstream commit correct description of what will happen when a AuthorizedKeysCommand is specified but AuthorizedKeysCommandUser is not (sshd will refuse to start) commit 161cf419f412446635013ac49e8c660cadc36080 Author: djm@openbsd.org Date: Mon Dec 22 07:55:51 2014 +0000 upstream commit make internal handling of filename arguments of "none" more consistent with ssh. "none" arguments are now replaced with NULL when the configuration is finalised. Simplifies checking later on (just need to test not-NULL rather than that + strcmp) and cleans up some inconsistencies. ok markus@ commit f69b69b8625be447b8826b21d87713874dac25a6 Author: djm@openbsd.org Date: Mon Dec 22 07:51:30 2014 +0000 upstream commit remember which public keys have been used for authentication and refuse to accept previously-used keys. This allows AuthenticationMethods=publickey,publickey to require that users authenticate using two _different_ pubkeys. ok markus@ commit 46ac2ed4677968224c4ca825bc98fc68dae183f0 Author: djm@openbsd.org Date: Mon Dec 22 07:24:11 2014 +0000 upstream commit fix passing of wildcard forward bind addresses when connection multiplexing is in use; patch from Sami Hartikainen via bz#2324; ok dtucker@ commit 0d1b241a262e4d0a6bbfdd595489ab1b853c43a1 Author: djm@openbsd.org Date: Mon Dec 22 06:14:29 2014 +0000 upstream commit make this slightly easier to diff against portable commit 0715bcdddbf68953964058f17255bf54734b8737 Author: Damien Miller Date: Mon Dec 22 13:47:07 2014 +1100 add missing regress output file commit 1e30483c8ad2c2f39445d4a4b6ab20c241e40593 Author: djm@openbsd.org Date: Mon Dec 22 02:15:52 2014 +0000 upstream commit adjust for new SHA256 key fingerprints and slightly-different MD5 hex fingerprint format commit 6b40567ed722df98593ad8e6a2d2448fc2b4b151 Author: djm@openbsd.org Date: Mon Dec 22 01:14:49 2014 +0000 upstream commit poll changes to netcat (usr.bin/netcat.c r1.125) broke this test; fix it by ensuring more stdio fds are sent to devnull commit a5375ccb970f49dddf7d0ef63c9b713ede9e7260 Author: jmc@openbsd.org Date: Sun Dec 21 23:35:14 2014 +0000 upstream commit tweak previous; commit b79efde5c3badf5ce4312fe608d8307eade533c5 Author: djm@openbsd.org Date: Sun Dec 21 23:12:42 2014 +0000 upstream commit document FingerprintHash here too commit d16bdd8027dd116afa01324bb071a4016cdc1a75 Author: Damien Miller Date: Mon Dec 22 10:18:09 2014 +1100 missing include for base64 encoding commit 56d1c83cdd1ac76f1c6bd41e01e80dad834f3994 Author: djm@openbsd.org Date: Sun Dec 21 22:27:55 2014 +0000 upstream commit Add FingerprintHash option to control algorithm used for key fingerprints. Default changes from MD5 to SHA256 and format from hex to base64. Feedback and ok naddy@ markus@ commit 058f839fe15c51be8b3a844a76ab9a8db550be4f Author: djm@openbsd.org Date: Thu Dec 18 23:58:04 2014 +0000 upstream commit don't count partial authentication success as a failure against MaxAuthTries; ok deraadt@ commit c7219f4f54d64d6dde66dbcf7a2699daa782d2a1 Author: djm@openbsd.org Date: Fri Dec 12 00:02:17 2014 +0000 upstream commit revert chunk I didn't mean to commit yet; via jmc@ commit 7de5991aa3997e2981440f39c1ea01273a0a2c7b Author: Damien Miller Date: Thu Dec 18 11:44:06 2014 +1100 upstream libc change revision 1.2 date: 2014/12/08 03:45:00; author: bcook; state: Exp; lines: +2 -2; commitid: 7zWEBgJJOCZ2hvTV; avoid left shift overflow in reallocarray. Some 64-bit platforms (e.g. Windows 64) have a 32-bit long. So, shifting 1UL 32-bits to the left causes an overflow. This replaces the constant 1UL with (size_t)1 so that we get the correct constant size for the platform. discussed with tedu@ & deraadt@ commit 2048f85a5e6da8bc6e0532efe02ecfd4e63c978c Author: Damien Miller Date: Thu Dec 18 10:15:49 2014 +1100 include CFLAGS in gnome askpass targets from Fedora commit 48b68ce19ca42fa488960028048dec023f7899bb Author: djm@openbsd.org Date: Thu Dec 11 08:20:09 2014 +0000 upstream commit explicitly include sys/param.h in files that use the howmany() macro; from portable commit d663bea30a294d440fef4398e5cd816317bd4518 Author: djm@openbsd.org Date: Thu Dec 11 05:25:06 2014 +0000 upstream commit mention AuthorizedKeysCommandUser must be set for AuthorizedKeysCommand to be run; bz#2287 commit 17bf3d81e00f2abb414a4fd271118cf4913f049f Author: djm@openbsd.org Date: Thu Dec 11 05:13:28 2014 +0000 upstream commit show in debug output which hostkeys are being tried when attempting hostbased auth; patch from Iain Morgan commit da0277e3717eadf5b15e03379fc29db133487e94 Author: djm@openbsd.org Date: Thu Dec 11 04:16:14 2014 +0000 upstream commit Make manual reflect reality: sftp-server's -d option accepts a "%d" option, not a "%h" one. bz#2316; reported by Kirk Wolf commit 4cf87f4b81fa9380bce5fcff7b0f8382ae3ad996 Author: djm@openbsd.org Date: Wed Dec 10 01:24:09 2014 +0000 upstream commit better error value for invalid signature length commit 4bfad14ca56f8ae04f418997816b4ba84e2cfc3c Author: Darren Tucker Date: Wed Dec 10 02:12:51 2014 +1100 Resync more with OpenBSD's rijndael.c, in particular "#if 0"-ing out some unused code. Should fix compile error reported by plautrba at redhat. commit 642652d280499691c8212ec6b79724b50008ce09 Author: Darren Tucker Date: Wed Dec 10 01:32:23 2014 +1100 Add reallocarray to compat library commit 3dfd8d93dfcc69261f5af99df56f3ff598581979 Author: djm@openbsd.org Date: Thu Dec 4 22:31:50 2014 +0000 upstream commit add tests for new client RevokedHostKeys option; refactor to make it a bit more readable commit a31046cad1aed16a0b55171192faa6d02665ccec Author: krw@openbsd.org Date: Wed Nov 19 13:35:37 2014 +0000 upstream commit Nuke yet more obvious #include duplications. ok deraadt@ commit a7c762e5b2c1093542c0bc1df25ccec0b4cf479f Author: djm@openbsd.org Date: Thu Dec 4 20:47:36 2014 +0000 upstream commit key_in_file() wrapper is no longer used commit 5e39a49930d885aac9c76af3129332b6e772cd75 Author: djm@openbsd.org Date: Thu Dec 4 02:24:32 2014 +0000 upstream commit add RevokedHostKeys option for the client Allow textfile or KRL-based revocation of hostkeys. commit 74de254bb92c684cf53461da97f52d5ba34ded80 Author: djm@openbsd.org Date: Thu Dec 4 01:49:59 2014 +0000 upstream commit convert KRL code to new buffer API ok markus@ commit db995f2eed5fc432598626fa3e30654503bf7151 Author: millert@openbsd.org Date: Wed Nov 26 18:34:51 2014 +0000 upstream commit Prefer setvbuf() to setlinebuf() for portability; ok deraadt@ commit 72bba3d179ced8b425272efe6956a309202a91f3 Author: jsg@openbsd.org Date: Mon Nov 24 03:39:22 2014 +0000 upstream commit Fix crashes in the handling of the sshd config file found with the afl fuzzer. ok deraadt@ djm@ commit 867f49c666adcfe92bf539d9c37c1accdea08bf6 Author: Damien Miller Date: Wed Nov 26 13:22:41 2014 +1100 Avoid Cygwin ssh-host-config reading /etc/group Patch from Corinna Vinschen commit 8b66f36291a721b1ba7c44f24a07fdf39235593e Author: Damien Miller Date: Wed Nov 26 13:20:35 2014 +1100 allow custom service name for sshd on Cygwin Permits the use of multiple sshd running with different service names. Patch by Florian Friesdorf via Corinna Vinschen commit 08c0eebf55d70a9ae1964399e609288ae3186a0c Author: jmc@openbsd.org Date: Sat Nov 22 19:21:03 2014 +0000 upstream commit restore word zapped in previous, and remove some useless "No" macros; commit a1418a0033fba43f061513e992e1cbcc3343e563 Author: deraadt@openbsd.org Date: Sat Nov 22 18:15:41 2014 +0000 upstream commit /dev/random has created the same effect as /dev/arandom (and /dev/urandom) for quite some time. Mop up the last few, by using /dev/random where we actually want it, or not even mentioning arandom where it is irrelevant. commit b6de5ac9ed421362f479d1ad4fa433d2e25dad5b Author: djm@openbsd.org Date: Fri Nov 21 01:00:38 2014 +0000 upstream commit fix NULL pointer dereference crash on invalid timestamp found using Michal Zalewski's afl fuzzer commit a1f8110cd5ed818d59b3a2964fab7de76e92c18e Author: mikeb@openbsd.org Date: Tue Nov 18 22:38:48 2014 +0000 upstream commit Sync AES code to the one shipped in OpenSSL/LibreSSL. This includes a commit made by Andy Polyakov to the OpenSSL source tree on Wed, 28 Jun 2006 with the following message: "Mitigate cache-collision timing attack on last round." OK naddy, miod, djm commit 335c83d5f35d8620e16b8aa26592d4f836e09ad2 Author: krw@openbsd.org Date: Tue Nov 18 20:54:28 2014 +0000 upstream commit Nuke more obvious #include duplications. ok deraadt@ millert@ tedu@ commit 51b64e44121194ae4bf153dee391228dada2abcb Author: djm@openbsd.org Date: Mon Nov 17 00:21:40 2014 +0000 upstream commit fix KRL generation when multiple CAs are in use We would generate an invalid KRL when revoking certs by serial number for multiple CA keys due to a section being written out twice. Also extend the regress test to catch this case by having it produce a multi-CA KRL. Reported by peter AT pean.org commit d2d51003a623e21fb2b25567c4878d915e90aa2a Author: djm@openbsd.org Date: Tue Nov 18 01:02:25 2014 +0000 upstream commit fix NULL pointer dereference crash in key loading found by Michal Zalewski's AFL fuzzer commit 9f9fad0191028edc43d100d0ded39419b6895fdf Author: djm@openbsd.org Date: Mon Nov 17 00:21:40 2014 +0000 upstream commit fix KRL generation when multiple CAs are in use We would generate an invalid KRL when revoking certs by serial number for multiple CA keys due to a section being written out twice. Also extend the regress test to catch this case by having it produce a multi-CA KRL. Reported by peter AT pean.org commit da8af83d3f7ec00099963e455010e0ed1d7d0140 Author: bentley@openbsd.org Date: Sat Nov 15 14:41:03 2014 +0000 upstream commit Reduce instances of `` '' in manuals. troff displays these as typographic quotes, but nroff implementations almost always print them literally, which rarely has the intended effect with modern fonts, even in stock xterm. These uses of `` '' can be replaced either with more semantic alternatives or with Dq, which prints typographic quotes in a UTF-8 locale (but will automatically fall back to `` '' in an ASCII locale). improvements and ok schwarze@ commit fc302561369483bb755b17f671f70fb894aec01d Author: djm@openbsd.org Date: Mon Nov 10 22:25:49 2014 +0000 upstream commit mux-related manual tweaks mention ControlPersist=0 is the same as ControlPersist=yes recommend that ControlPath sockets be placed in a og-w directory commit 0e4cff5f35ed11102fe3783779960ef07e0cd381 Author: Damien Miller Date: Wed Nov 5 11:01:31 2014 +1100 Prepare scripts for next Cygwin release Makes the Cygwin-specific ssh-user-config script independent of the existence of /etc/passwd. The next Cygwin release will allow to generate passwd and group entries from the Windows account DBs, so the scripts have to adapt. from Corinna Vinschen commit 7d0ba5336651731949762eb8877ce9e3b52df436 Author: Damien Miller Date: Thu Oct 30 10:45:41 2014 +1100 include version number in OpenSSL-too-old error commit 3bcb92e04d9207e9f78d82f7918c6d3422054ce9 Author: lteo@openbsd.org Date: Fri Oct 24 02:01:20 2014 +0000 upstream commit Remove unnecessary include: netinet/in_systm.h is not needed by these programs. NB. skipped for portable ok deraadt@ millert@ commit 6fdcaeb99532e28a69f1a1599fbd540bb15b70a0 Author: djm@openbsd.org Date: Mon Oct 20 03:43:01 2014 +0000 upstream commit whitespace commit 165bc8786299e261706ed60342985f9de93a7461 Author: daniel@openbsd.org Date: Tue Oct 14 03:09:59 2014 +0000 upstream commit plug a memory leak; from Maxime Villard. ok djm@ commit b1ba15f3885947c245c2dbfaad0a04ba050abea0 Author: jmc@openbsd.org Date: Thu Oct 9 06:21:31 2014 +0000 upstream commit tweak previous; commit 259a02ebdf74ad90b41d116ecf70aa823fa4c6e7 Author: djm@openbsd.org Date: Mon Oct 13 00:38:35 2014 +0000 upstream commit whitespace commit 957fbceb0f3166e41b76fdb54075ab3b9cc84cba Author: djm@openbsd.org Date: Wed Oct 8 22:20:25 2014 +0000 upstream commit Tweak config reparsing with host canonicalisation Make the second pass through the config files always run when hostname canonicalisation is enabled. Add a "Match canonical" criteria that allows ssh_config Match blocks to trigger only in the second config pass. Add a -G option to ssh that causes it to parse its configuration and dump the result to stdout, similar to "sshd -T" Allow ssh_config Port options set in the second config parse phase to be applied (they were being ignored). bz#2267 bz#2286; ok markus commit 5c0dafd38bf66feeeb45fa0741a5baf5ad8039ba Author: djm@openbsd.org Date: Wed Oct 8 22:15:27 2014 +0000 upstream commit another -Wpointer-sign from clang commit bb005dc815ebda9af3ae4b39ca101c4da918f835 Author: djm@openbsd.org Date: Wed Oct 8 22:15:06 2014 +0000 upstream commit fix a few -Wpointer-sign warnings from clang commit 3cc1fbb4fb0e804bfb873fd363cea91b27fc8188 Author: djm@openbsd.org Date: Wed Oct 8 21:45:48 2014 +0000 upstream commit parse cert sections using nested buffers to reduce copies; ok markus commit 4a45922aebf99164e2fc83d34fe55b11ae1866ef Author: djm@openbsd.org Date: Mon Oct 6 00:47:15 2014 +0000 upstream commit correct options in usage(); from mancha1 AT zoho.com commit 48dffd5bebae6fed0556dc5c36cece0370690618 Author: djm@openbsd.org Date: Tue Sep 9 09:45:36 2014 +0000 upstream commit mention permissions on tun(4) devices in PermitTunnel documentation; bz#2273 commit a5883d4eccb94b16c355987f58f86a7dee17a0c2 Author: djm@openbsd.org Date: Wed Sep 3 18:55:07 2014 +0000 upstream commit tighten permissions on pty when the "tty" group does not exist; pointed out by Corinna Vinschen; ok markus commit 180bcb406b58bf30723c01a6b010e48ee626dda8 Author: sobrado@openbsd.org Date: Sat Aug 30 16:32:25 2014 +0000 upstream commit typo. commit f70b22bcdd52f6bf127047b3584371e6e5d45627 Author: sobrado@openbsd.org Date: Sat Aug 30 15:33:50 2014 +0000 upstream commit improve capitalization for the Ed25519 public-key signature system. ok djm@ commit 7df8818409c752cf3f0c3f8044fe9aebed8647bd Author: doug@openbsd.org Date: Thu Aug 21 01:08:52 2014 +0000 upstream commit Free resources on error in mkstemp and fdopen ok djm@ commit 40ba4c9733aaed08304714faeb61529f18da144b Author: deraadt@openbsd.org Date: Wed Aug 20 01:28:55 2014 +0000 upstream commit djm how did you make a typo like that... commit 57d378ec9278ba417a726f615daad67d157de666 Author: djm@openbsd.org Date: Tue Aug 19 23:58:28 2014 +0000 upstream commit When dumping the server configuration (sshd -T), print correct KEX, MAC and cipher defaults. Spotted by Iain Morgan commit 7ff880ede5195d0b17e7f1e3b6cfbc4cb6f85240 Author: djm@openbsd.org Date: Tue Aug 19 23:57:18 2014 +0000 upstream commit ~-expand lcd paths commit 4460a7ad0c78d4cd67c467f6e9f4254d0404ed59 Author: Damien Miller Date: Sun Oct 12 12:35:48 2014 +1100 remove duplicated KEX_DH1 entry commit c9b8426a616138d0d762176c94f51aff3faad5ff Author: Damien Miller Date: Thu Oct 9 10:34:06 2014 +1100 remove ChangeLog file Commit logs will be generated from git at release time. commit 81d18ff7c93a04affbf3903e0963859763219aed Author: Damien Miller Date: Tue Oct 7 21:24:25 2014 +1100 delete contrib/caldera directory commit 0ec9e87d3638206456968202f05bb5123670607a Author: Damien Miller Date: Tue Oct 7 19:57:27 2014 +1100 test commit commit 8fb65a44568701b779f3d77326bceae63412d28d Author: Damien Miller Date: Tue Oct 7 09:21:49 2014 +1100 - (djm) Release OpenSSH-6.7 commit e8c9f2602c46f6781df5e52e6cd8413dab4602a3 Author: Damien Miller Date: Fri Oct 3 09:24:56 2014 +1000 - (djm) [sshd_config.5] typo; from Iain Morgan commit 703b98a26706f5083801d11059486d77491342ae Author: Damien Miller Date: Wed Oct 1 09:43:07 2014 +1000 - (djm) [openbsd-compat/Makefile.in openbsd-compat/kludge-fd_set.c] [openbsd-compat/openbsd-compat.h] Kludge around bad glibc _FORTIFY_SOURCE check that doesn't grok heap-allocated fd_sets; ok dtucker@ commit 0fa0ed061bbfedb0daa705e220748154a84c3413 Author: Damien Miller Date: Wed Sep 10 08:15:34 2014 +1000 - (djm) [sandbox-seccomp-filter.c] Allow mremap and exit for DietLibc; patch from Felix von Leitner; ok dtucker commit ad7d23d461c3b7e1dcb15db13aee5f4b94dc1a95 Author: Darren Tucker Date: Tue Sep 9 12:23:10 2014 +1000 20140908 - (dtucker) [INSTALL] Update info about egd. ok djm@ commit 2a8699f37cc2515e3bc60e0c677ba060f4d48191 Author: Damien Miller Date: Thu Sep 4 03:46:05 2014 +1000 - (djm) [openbsd-compat/arc4random.c] Zero seed after keying PRNG commit 44988defb1f5e3afe576d86000365e1f07a1b494 Author: Damien Miller Date: Wed Sep 3 05:35:32 2014 +1000 - (djm) [contrib/cygwin/ssh-host-config] Fix old code leading to permissions/ACLs; from Corinna Vinschen commit 23f269562b7537b2f6f5014e50a25e5dcc55a837 Author: Damien Miller Date: Wed Sep 3 05:33:25 2014 +1000 - (djm) [defines.h sshbuf.c] Move __predict_true|false to defines.h and conditionalise to avoid duplicate definition. commit 41c8de2c0031cf59e7cf0c06b5bcfbf4852c1fda Author: Damien Miller Date: Sat Aug 30 16:23:06 2014 +1000 - (djm) [Makefile.in] Make TEST_SHELL a variable; "good idea" tim@ commit d7c81e216a7bd9eed6e239c970d9261bb1651947 Author: Damien Miller Date: Sat Aug 30 04:18:28 2014 +1000 - (djm) [openbsd-compat/openssl-compat.h] add include guard commit 4687802dda57365b984b897fc3c8e2867ea09b22 Author: Damien Miller Date: Sat Aug 30 03:29:19 2014 +1000 - (djm) [misc.c] Missing newline between functions commit 51c77e29220dee87c53be2dc47092934acab26fe Author: Damien Miller Date: Sat Aug 30 02:30:30 2014 +1000 - (djm) [openbsd-compat/openssl-compat.h] add OPENSSL_[RD]SA_MAX_MODULUS_BITS defines for OpenSSL that lacks them commit 3d673d103bad35afaec6e7ef73e5277216ce33a3 Author: Damien Miller Date: Wed Aug 27 06:32:01 2014 +1000 - (djm) [openbsd-compat/explicit_bzero.c] implement explicit_bzero() using memset_s() where possible; improve fallback to indirect bzero via a volatile pointer to give it more of a chance to avoid being optimised away. commit 146218ac11a1eb0dcade6f793d7acdef163b5ddc Author: Damien Miller Date: Wed Aug 27 04:11:55 2014 +1000 - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth monitor, not preauth; bz#2263 commit 1b215c098b3b37e38aa4e4c91bb908eee41183b1 Author: Damien Miller Date: Wed Aug 27 04:04:40 2014 +1000 - (djm) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] [regress/unittests/sshkey/common.c] [regress/unittests/sshkey/test_file.c] [regress/unittests/sshkey/test_fuzz.c] [regress/unittests/sshkey/test_sshkey.c] Don't include openssl/ec.h on !ECC OpenSSL systems commit ad013944af0a19e3f612089d0099bb397cf6502d Author: Damien Miller Date: Tue Aug 26 09:27:28 2014 +1000 - (djm) [INSTALL] Recommend libcrypto be built -fPIC, mention LibreSSL, update OpenSSL version requirement. commit ed126de8ee04c66640a0ea2697c4aaf36801f100 Author: Damien Miller Date: Tue Aug 26 08:37:47 2014 +1000 - (djm) [bufec.c] Skip this file on !ECC OpenSSL commit 9c1dede005746864a4fdb36a7cdf6c51296ca909 Author: Damien Miller Date: Sun Aug 24 03:01:06 2014 +1000 - (djm) [sftp-server.c] Some systems (e.g. Irix) have prctl() but not PR_SET_DUMPABLE, so adjust ifdef; reported by Tom Christensen commit d244a5816fd1312a33404b436e4dd83594f1119e Author: Damien Miller Date: Sat Aug 23 17:06:49 2014 +1000 - (djm) [configure.ac] We now require a working vsnprintf everywhere (not just for systems that lack asprintf); check for it always and extend test to catch more brokenness. Fixes builds on Solaris <= 9 commit 4cec036362a358e398e6a2e6d19d8e5780558634 Author: Damien Miller Date: Sat Aug 23 03:11:09 2014 +1000 - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on lastlog writing on platforms with high UIDs; bz#2263 commit 394a60f2598d28b670d934b93942a3370b779b39 Author: Damien Miller Date: Fri Aug 22 18:06:20 2014 +1000 - (djm) [configure.ac] double braces to appease autoconf commit 4d69aeabd6e60afcdc7cca177ca751708ab79a9d Author: Damien Miller Date: Fri Aug 22 17:48:27 2014 +1000 - (djm) [openbsd-compat/bsd-snprintf.c] Fix compilation failure (prototype/ definition mismatch) and warning for broken/missing snprintf case. commit 0c11f1ac369d2c0aeb0ab0458a7cd04c72fe5e9e Author: Damien Miller Date: Fri Aug 22 17:36:56 2014 +1000 - (djm) [sshbuf-getput-crypto.c] Fix compilation when OpenSSL lacks ECC commit 6d62784b8973340b251fea6b04890f471adf28db Author: Damien Miller Date: Fri Aug 22 17:36:19 2014 +1000 - (djm) [configure.ac] include leading zero characters in OpenSSL version number; fixes test for unsupported versions commit 4f1ff1ed782117f5d5204d4e91156ed5da07cbb7 Author: Damien Miller Date: Thu Aug 21 15:54:50 2014 +1000 - (djm) [regress/unittests/test_helper/test_helper.c] Fix for systems that don't set __progname. Diagnosed by Tom Christensen. commit 005a64da0f457410045ef0bfa93c863c2450447d Author: Damien Miller Date: Thu Aug 21 10:48:41 2014 +1000 - (djm) [key.h] Fix ifdefs for no-ECC OpenSSL commit aa6598ebb3343c7380e918388e10e8ca5852b613 Author: Damien Miller Date: Thu Aug 21 10:47:54 2014 +1000 - (djm) [Makefile.in] fix reference to libtest_helper.a in sshkey test too. commit 54703e3cf63f0c80d4157e5ad7dbc2b363ee2c56 Author: Damien Miller Date: Wed Aug 20 11:10:51 2014 +1000 - (djm) [contrib/cygwin/README] Correct build instructions; from Corinna commit f0935698f0461f24d8d1f1107b476ee5fd4db1cb Author: Damien Miller Date: Wed Aug 20 11:06:50 2014 +1000 - (djm) [sshkey.h] Fix compilation when OpenSSL lacks ECC commit c5089ecaec3b2c02f014f4e67518390702a4ba14 Author: Damien Miller Date: Wed Aug 20 11:06:20 2014 +1000 - (djm) [Makefile.in] refer to libtest_helper.a by explicit path rather than -L/-l; fixes linking problems on some platforms commit 2195847e503a382f83ee969b0a8bd3dfe0e55c18 Author: Damien Miller Date: Wed Aug 20 11:05:03 2014 +1000 - (djm) [configure.ac] Check OpenSSL version is supported at configure time; suggested by Kevin Brott commit a75aca1bbc989aa9f8b1b08489d37855f3d24d1a Author: Damien Miller Date: Tue Aug 19 11:36:07 2014 +1000 - (djm) [INSTALL contrib/caldera/openssh.spec contrib/cygwin/README] [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Remove mentions of TCP wrappers. commit 3f022b5a9477abceeb1bbeab04b055f3cc7ca8f6 Author: Damien Miller Date: Tue Aug 19 11:32:34 2014 +1000 - (djm) [ssh-dss.c] Include openssl/dsa.h for DSA_SIG commit 88137902632aceb923990e98cf5dc923bb3ef2f5 Author: Damien Miller Date: Tue Aug 19 11:28:11 2014 +1000 - (djm) [sshbuf.h] Fix compilation on systems without OPENSSL_HAS_ECC. commit 2f3d1e7fb2eabd3cfbfd8d0f7bdd2f9a1888690b Author: Damien Miller Date: Tue Aug 19 11:14:36 2014 +1000 - (djm) [myproposal.h] Make curve25519 KEX dependent on HAVE_EVP_SHA256 instead of OPENSSL_HAS_ECC. commit d4e7d59d01a6c7f59e8c1f94a83c086e9a33d8aa Author: Damien Miller Date: Tue Aug 19 11:14:17 2014 +1000 - (djm) [serverloop.c] Fix syntax error on Cygwin; from Corinna Vinschen commit 9eaeea2cf2b6af5f166cfa9ad3c7a90711a147a9 Author: Damien Miller Date: Sun Aug 10 11:35:05 2014 +1000 - (djm) [README contrib/caldera/openssh.spec] [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Update versions commit f8988fbef0c9801d19fa2f8f4f041690412bec37 Author: Damien Miller Date: Fri Aug 1 13:31:52 2014 +1000 - (djm) [regress/multiplex.sh] Use -d (detach stdin) flag to disassociate nc from stdin, it's more portable commit 5b3879fd4b7a4e3d43bab8f40addda39bc1169d0 Author: Damien Miller Date: Fri Aug 1 12:28:31 2014 +1000 - (djm) [regress/multiplex.sh] Instruct nc not to quit as soon as stdin is closed; avoid regress failures when stdin is /dev/null commit a9c46746d266f8a1b092a72b2150682d1af8ebfc Author: Damien Miller Date: Fri Aug 1 12:26:49 2014 +1000 - (djm) [regress/multiplex.sh] Skip test for non-OpenBSD netcat. We need a better solution, but this will have to do for now. commit 426117b2e965e43f47015942b5be8dd88fe74b88 Author: Damien Miller Date: Wed Jul 30 12:33:20 2014 +1000 - schwarze@cvs.openbsd.org 2014/07/28 15:40:08 [sftp-server.8 sshd_config.5] some systems no longer need /dev/log; issue noticed by jirib; ok deraadt commit f497794b6962eaf802ab4ac2a7b22ae591cca1d5 Author: Damien Miller Date: Wed Jul 30 12:32:46 2014 +1000 - dtucker@cvs.openbsd.org 2014/07/25 21:22:03 [ssh-agent.c] Clear buffer used for handling messages. This prevents keys being left in memory after they have been expired or deleted in some cases (but note that ssh-agent is setgid so you would still need root to access them). Pointed out by Kevin Burns, ok deraadt commit a8a0f65c57c8ecba94d65948e9090da54014dfef Author: Damien Miller Date: Wed Jul 30 12:32:28 2014 +1000 - OpenBSD CVS Sync - millert@cvs.openbsd.org 2014/07/24 22:57:10 [ssh.1] Mention UNIX-domain socket forwarding too. OK jmc@ deraadt@ commit 56b840f2b81e14a2f95c203403633a72566736f8 Author: Damien Miller Date: Fri Jul 25 08:11:30 2014 +1000 - (djm) [regress/multiplex.sh] restore incorrectly deleted line; pointed out by Christian Hesse commit dd417b60d5ca220565d1014e92b7f8f43dc081eb Author: Darren Tucker Date: Wed Jul 23 10:41:21 2014 +1000 - dtucker@cvs.openbsd.org 2014/07/22 23:35:38 [regress/unittests/sshkey/testdata/*] Regenerate test keys with certs signed with ed25519 instead of ecdsa. These can be used in -portable on platforms that don't support ECDSA. commit 40e50211896369dba8f64f3b5e5fd58b76f5ac3f Author: Darren Tucker Date: Wed Jul 23 10:35:45 2014 +1000 - dtucker@cvs.openbsd.org 2014/07/22 23:57:40 [regress/unittests/sshkey/mktestdata.sh] Add $OpenBSD tag to make syncs easier commit 07e644251e809b1d4c062cf85bd1146a7e3f5a8a Author: Darren Tucker Date: Wed Jul 23 10:34:26 2014 +1000 - dtucker@cvs.openbsd.org 2014/07/22 23:23:22 [regress/unittests/sshkey/mktestdata.sh] Sign test certs with ed25519 instead of ecdsa so that they'll work in -portable on platforms that don't have ECDSA in their OpenSSL. ok djm commit cea099a7c4eaecb01b001e5453bb4e5c25006c22 Author: Darren Tucker Date: Wed Jul 23 10:04:02 2014 +1000 - djm@cvs.openbsd.org 2014/07/22 01:32:12 [regress/multiplex.sh] change the test for still-open Unix domain sockets to be robust against nc implementations that produce error messages. from -portable (Id sync only) commit 31eb78078d349b32ea41952ecc944b3ad6cb0d45 Author: Darren Tucker Date: Wed Jul 23 09:43:42 2014 +1000 - guenther@cvs.openbsd.org 2014/07/22 07:13:42 [umac.c] Convert from to the shiney new ok dtucker@, who also confirmed that -portable handles this already (ID sync only, includes.h pulls in endian.h if available.) commit 820763efef2d19d965602533036c2b4badc9d465 Author: Darren Tucker Date: Wed Jul 23 09:40:46 2014 +1000 - dtucker@cvs.openbsd.org 2014/07/22 01:18:50 [key.c] Prevent spam from key_load_private_pem during hostbased auth. ok djm@ commit c4ee219a66f3190fa96cbd45b4d11015685c6306 Author: Darren Tucker Date: Wed Jul 23 04:27:50 2014 +1000 - (dtucker) [regress/unittests/sshkey/test_{file,fuzz,sshkey}.c] Wrap ecdsa- specific tests inside OPENSSL_HAS_ECC. commit 04f4824940ea3edd60835416ececbae16438968a Author: Damien Miller Date: Tue Jul 22 11:31:47 2014 +1000 - (djm) [regress/multiplex.sh] change the test for still-open Unix domain sockets to be robust against nc implementations that produce error messages. commit 5ea4fe00d55453aaa44007330bb4c3181bd9b796 Author: Damien Miller Date: Tue Jul 22 09:39:19 2014 +1000 - (djm) [regress/multiplex.sh] ssh mux master lost -N somehow; put it back commit 948a1774a79a85f9deba6d74db95f402dee32c69 Author: Darren Tucker Date: Tue Jul 22 01:07:11 2014 +1000 - (dtucker) [sshkey.c] ifdef out unused variable when compiling without OPENSSL_HAS_ECC. commit c8f610f6cc57ae129758052439d9baf13699097b Author: Damien Miller Date: Mon Jul 21 10:23:27 2014 +1000 - (djm) [regress/multiplex.sh] Not all netcat accept the -N option. commit 0e4e95566cd95c887f69272499b8f3880b3ec0f5 Author: Damien Miller Date: Mon Jul 21 09:52:54 2014 +1000 - millert@cvs.openbsd.org 2014/07/15 15:54:15 [forwarding.sh multiplex.sh] Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket. This is a reimplementation of the streamlocal patches by William Ahern from: http://www.25thandclement.com/~william/projects/streamlocal.html OK djm@ markus@ commit 93a87ab27ecdc709169fb24411133998f81e2761 Author: Darren Tucker Date: Mon Jul 21 06:30:25 2014 +1000 - (dtucker) [regress/unittests/sshkey/ {common,test_file,test_fuzz,test_sshkey}.c] Wrap stdint.h includes in ifdefs. commit 5573171352ea23df2dc6d2fe0324d023b7ba697c Author: Darren Tucker Date: Mon Jul 21 02:24:59 2014 +1000 - (dtucker) [cipher.c openbsd-compat/openssl-compat.h] Restore the bits needed to build AES CTR mode against OpenSSL 0.9.8f and above. ok djm commit 74e28682711d005026c7c8f15f96aea9d3c8b5a3 Author: Tim Rice Date: Fri Jul 18 20:00:11 2014 -0700 - (tim) [openbsd-compat/port-uw.c] Include misc.h for fwd_opts, used in servconf.h. commit d1a0421f8e5e933fee6fb58ee6b9a22c63c8a613 Author: Darren Tucker Date: Sat Jul 19 07:23:55 2014 +1000 - (dtucker) [key.c sshkey.c] Put new ecdsa bits inside ifdef OPENSSL_HAS_ECC. commit f0fe9ea1be62227c130b317769de3d1e736b6dc1 Author: Darren Tucker Date: Sat Jul 19 06:33:12 2014 +1000 - (dtucker) [Makefile.in] Add a t-exec target to run just the executable tests. commit 450bc1180d4b061434a4b733c5c8814fa30b022b Author: Darren Tucker Date: Sat Jul 19 06:23:18 2014 +1000 - (dtucker) [auth2-gss.c gss-serv-krb5.c] Include misc.h for fwd_opts, used in servconf.h. commit ab2ec586baad122ed169285c31927ccf58bc7b28 Author: Damien Miller Date: Fri Jul 18 15:04:47 2014 +1000 - djm@cvs.openbsd.org 2014/07/18 02:46:01 [ssh-agent.c] restore umask around listener socket creation (dropped in streamlocal patch merge) commit 357610d15946381ae90c271837dcdd0cdce7145f Author: Damien Miller Date: Fri Jul 18 15:04:10 2014 +1000 - djm@cvs.openbsd.org 2014/07/17 07:22:19 [mux.c ssh.c] reflect stdio-forward ("ssh -W host:port ...") failures in exit status. previously we were always returning 0. bz#2255 reported by Brendan Germain; ok dtucker commit dad9a4a0b7c2b5d78605f8df28718f116524134e Author: Damien Miller Date: Fri Jul 18 15:03:49 2014 +1000 - djm@cvs.openbsd.org 2014/07/17 00:12:03 [key.c] silence "incorrect passphrase" error spam; reported and ok dtucker@ commit f42f7684ecbeec6ce50e0310f80b3d6da2aaf533 Author: Damien Miller Date: Fri Jul 18 15:03:27 2014 +1000 - djm@cvs.openbsd.org 2014/07/17 00:10:18 [mux.c] preserve errno across syscall commit 1b83320628cb0733e3688b85bfe4d388a7c51909 Author: Damien Miller Date: Fri Jul 18 15:03:02 2014 +1000 - djm@cvs.openbsd.org 2014/07/17 00:10:56 [sandbox-systrace.c] ifdef SYS_sendsyslog so this will compile without patching on -stable commit 6d57656331bcd754d912950e4a18ad259d596e61 Author: Damien Miller Date: Fri Jul 18 15:02:06 2014 +1000 - jmc@cvs.openbsd.org 2014/07/16 14:48:57 [ssh.1] add the streamlocal* options to ssh's -o list; millert says they're irrelevant for scp/sftp; ok markus millert commit 7acefbbcbeab725420ea07397ae35992f505f702 Author: Damien Miller Date: Fri Jul 18 14:11:24 2014 +1000 - millert@cvs.openbsd.org 2014/07/15 15:54:14 [PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] [sshd_config.5 sshlogin.c] Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket. This is a reimplementation of the streamlocal patches by William Ahern from: http://www.25thandclement.com/~william/projects/streamlocal.html OK djm@ markus@ commit 6262d760e00714523633bd989d62e273a3dca99a Author: Damien Miller Date: Thu Jul 17 09:52:07 2014 +1000 - tedu@cvs.openbsd.org 2014/07/11 13:54:34 [myproposal.h] by popular demand, add back hamc-sha1 to server proposal for better compat with many clients still in use. ok deraadt commit 9d69d937b46ecba17f16d923e538ceda7b705c7a Author: Damien Miller Date: Thu Jul 17 09:49:37 2014 +1000 - deraadt@cvs.openbsd.org 2014/07/11 08:09:54 [sandbox-systrace.c] Permit use of SYS_sendsyslog from inside the sandbox. Clock is ticking, update your kernels and sshd soon.. libc will start using sendsyslog() in about 4 days. commit f6293a0b4129826fc2e37e4062f96825df43c326 Author: Damien Miller Date: Thu Jul 17 09:01:25 2014 +1000 - (djm) [digest-openssl.c] Preserve array order when disabling digests. Reported by Petr Lautrbach. commit 00f9cd230709c04399ef5ff80492d70a55230694 Author: Damien Miller Date: Tue Jul 15 10:41:38 2014 +1000 - (djm) [configure.ac] Delay checks for arc4random* until after libcrypto has been located; fixes builds agains libressl-portable commit 1d0df3249c87019556b83306c28d4769375c2edc Author: Damien Miller Date: Fri Jul 11 09:19:04 2014 +1000 - OpenBSD CVS Sync - benno@cvs.openbsd.org 2014/07/09 14:15:56 [ssh-add.c] fix ssh-add crash while loading more than one key ok markus@ commit 7a57eb3d105aa4ced15fb47001092c58811e6d9d Author: Damien Miller Date: Wed Jul 9 13:22:31 2014 +1000 - djm@cvs.openbsd.org 2014/07/07 08:15:26 [multiplex.sh] remove forced-fatal that I stuck in there to test the new cleanup logic and forgot to remove... commit 612f965239a30fe536b11ece1834d9f470aeb029 Author: Damien Miller Date: Wed Jul 9 13:22:03 2014 +1000 - djm@cvs.openbsd.org 2014/07/06 07:42:03 [multiplex.sh test-exec.sh] add a hook to the cleanup() function to kill $SSH_PID if it is set use it to kill the mux master started in multiplex.sh (it was being left around on fatal failures) commit d0bb950485ba121e43a77caf434115ed6417b46f Author: Damien Miller Date: Wed Jul 9 13:07:28 2014 +1000 - djm@cvs.openbsd.org 2014/07/09 03:02:15 [key.c] downgrade more error() to debug() to better match what old authfile.c did; suppresses spurious errors with hostbased authentication enabled commit 0070776a038655c57f57e70cd05e4c38a5de9d84 Author: Damien Miller Date: Wed Jul 9 13:07:06 2014 +1000 - djm@cvs.openbsd.org 2014/07/09 01:45:10 [sftp.c] more useful error message when GLOB_NOSPACE occurs; bz#2254, patch from Orion Poplawski commit 079bac2a43c74ef7cf56850afbab3b1932534c50 Author: Damien Miller Date: Wed Jul 9 13:06:25 2014 +1000 - djm@cvs.openbsd.org 2014/07/07 08:19:12 [ssh_config.5] mention that ProxyCommand is executed using shell "exec" to avoid a lingering process; bz#1977 commit 3a48cc090096cf99b9de592deb5f90e444edebfb Author: Damien Miller Date: Sun Jul 6 09:32:49 2014 +1000 - djm@cvs.openbsd.org 2014/07/05 23:11:48 [channels.c] fix remote-forward cancel regression; ok markus@ commit 48bae3a38cb578713e676708164f6e7151cc64fa Author: Damien Miller Date: Sun Jul 6 09:27:06 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 23:18:35 [authfile.h] remove leakmalloc droppings commit 72e6b5c9ed5e72ca3a6ccc3177941b7c487a0826 Author: Damien Miller Date: Fri Jul 4 09:00:04 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 22:40:43 [servconf.c servconf.h session.c sshd.8 sshd_config.5] Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option; bz#2160; ok markus@ commit 602943d1179a08dfa70af94f62296ea5e3d6ebb8 Author: Damien Miller Date: Fri Jul 4 08:59:41 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 22:33:41 [channels.c] allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family; bz#2222 ok markus@ commit 6b37fbb7921d156b31e2c8f39d9e1b6746c34983 Author: Damien Miller Date: Fri Jul 4 08:59:24 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 22:23:46 [sshconnect.c] when rekeying, skip file/DNS lookup if it is the same as the key sent during initial key exchange. bz#2154 patch from Iain Morgan; ok markus@ commit d2c3cd5f2e47ee24cf7093ce8e948c2e79dfc3fd Author: Damien Miller Date: Fri Jul 4 08:59:01 2014 +1000 - jsing@cvs.openbsd.org 2014/07/03 12:42:16 [cipher-chachapoly.c] Call chacha_ivsetup() immediately before chacha_encrypt_bytes() - this makes it easier to verify that chacha_encrypt_bytes() is only called once per chacha_ivsetup() call. ok djm@ commit 686feb560ec43a06ba04da82b50f3c183c947309 Author: Damien Miller Date: Thu Jul 3 21:29:38 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 11:16:55 [auth.c auth.h auth1.c auth2.c] make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages; bz#2199, ok dtucker commit 0f12341402e18fd9996ec23189b9418d2722453f Author: Damien Miller Date: Thu Jul 3 21:28:09 2014 +1000 - jmc@cvs.openbsd.org 2014/07/03 07:45:27 [ssh_config.5] escape %C since groff thinks it part of an Rs/Re block; commit 9c38643c5cd47a19db2cc28279dcc28abadc22b3 Author: Damien Miller Date: Thu Jul 3 21:27:46 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 06:39:19 [ssh.c ssh_config.5] Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a has of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding sockaddr_un's miserly pathname limits for mux control paths. bz#2220, based on patch from mancha1 AT zoho.com; ok markus@ commit 49d9bfe2b2f3e90cc158a215dffa7675e57e7830 Author: Damien Miller Date: Thu Jul 3 21:26:42 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 05:38:17 [ssh.1] document that -g will only work in the multiplexed case if applied to the mux master commit ef9f13ba4c58057b2166d1f2e790535da402fbe5 Author: Damien Miller Date: Thu Jul 3 21:26:21 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 05:32:36 [ssh_config.5] mention '%%' escape sequence in HostName directives and how it may be used to specify IPv6 link-local addresses commit e6a407789e5432dd2e53336fb73476cc69048c54 Author: Damien Miller Date: Thu Jul 3 21:25:03 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 04:36:45 [digest.h] forward-declare struct sshbuf so consumers don't need to include sshbuf.h commit 4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919 Author: Damien Miller Date: Thu Jul 3 21:24:40 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 03:47:27 [ssh-keygen.c] When hashing or removing hosts using ssh-keygen, don't choke on @revoked markers and don't remove @cert-authority markers; bz#2241, reported by mlindgren AT runelind.net commit e5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 Author: Damien Miller Date: Thu Jul 3 21:24:19 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 03:34:09 [gss-serv.c session.c ssh-keygen.c] standardise on NI_MAXHOST for gethostname() string lengths; about 1/2 the cases were using it already. Fixes bz#2239 en passant commit c174a3b7c14e0d178c61219de2aa1110e209950c Author: Damien Miller Date: Thu Jul 3 21:23:24 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 03:26:43 [digest-openssl.c] use EVP_Digest() for one-shot hash instead of creating, updating, finalising and destroying a context. bz#2231, based on patch from Timo Teras commit d7ca2cd31ecc4d63a055e2dcc4bf35c13f2db4c5 Author: Damien Miller Date: Thu Jul 3 21:23:01 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 03:15:01 [ssh-add.c] make stdout line-buffered; saves partial output getting lost when ssh-add fatal()s part-way through (e.g. when listing keys from an agent that supports key types that ssh-add doesn't); bz#2234, reported by Phil Pennock commit b1e967c8d7c7578dd0c172d85b3046cf54ea42ba Author: Damien Miller Date: Thu Jul 3 21:22:40 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 03:11:03 [ssh-agent.c] Only cleanup agent socket in the main agent process and not in any subprocesses it may have started (e.g. forked askpass). Fixes agent sockets being zapped when askpass processes fatal(); bz#2236 patch from Dmitry V. Levin commit 61e28e55c3438d796b02ef878bcd28620d452670 Author: Damien Miller Date: Thu Jul 3 21:22:22 2014 +1000 - djm@cvs.openbsd.org 2014/07/03 01:45:38 [sshkey.c] make Ed25519 keys' title fit properly in the randomart border; bz#2247 based on patch from Christian Hesse commit 9eb4cd9a32c32d40d36450b68ed93badc6a94c68 Author: Damien Miller Date: Thu Jul 3 13:29:50 2014 +1000 - (djm) [monitor_fdpass.c] Use sys/poll.h if poll.h doesn't exist; bz#2237 commit 8da0fa24934501909408327298097b1629b89eaa Author: Damien Miller Date: Thu Jul 3 11:54:19 2014 +1000 - (djm) [digest-openssl.c configure.ac] Disable RIPEMD160 if libcrypto doesn't support it. commit 81309c857dd0dbc0a1245a16d621c490ad48cfbb Author: Damien Miller Date: Wed Jul 2 17:45:55 2014 +1000 - (djm) [regress/Makefile] fix execution of sshkey unit/fuzz test commit 82b2482ce68654815ee049b9bf021bb362a35ff2 Author: Damien Miller Date: Wed Jul 2 17:43:41 2014 +1000 - (djm) [sshkey.c] Conditionalise inclusion of util.h commit dd8b1dd7933eb6f5652641b0cdced34a387f2e80 Author: Damien Miller Date: Wed Jul 2 17:38:31 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 01:14:17 [Makefile.in regress/Makefile regress/unittests/Makefile] [regress/unittests/sshkey/Makefile] [regress/unittests/sshkey/common.c] [regress/unittests/sshkey/common.h] [regress/unittests/sshkey/mktestdata.sh] [regress/unittests/sshkey/test_file.c] [regress/unittests/sshkey/test_fuzz.c] [regress/unittests/sshkey/test_sshkey.c] [regress/unittests/sshkey/tests.c] [regress/unittests/sshkey/testdata/dsa_1] [regress/unittests/sshkey/testdata/dsa_1-cert.fp] [regress/unittests/sshkey/testdata/dsa_1-cert.pub] [regress/unittests/sshkey/testdata/dsa_1.fp] [regress/unittests/sshkey/testdata/dsa_1.fp.bb] [regress/unittests/sshkey/testdata/dsa_1.param.g] [regress/unittests/sshkey/testdata/dsa_1.param.priv] [regress/unittests/sshkey/testdata/dsa_1.param.pub] [regress/unittests/sshkey/testdata/dsa_1.pub] [regress/unittests/sshkey/testdata/dsa_1_pw] [regress/unittests/sshkey/testdata/dsa_2] [regress/unittests/sshkey/testdata/dsa_2.fp] [regress/unittests/sshkey/testdata/dsa_2.fp.bb] [regress/unittests/sshkey/testdata/dsa_2.pub] [regress/unittests/sshkey/testdata/dsa_n] [regress/unittests/sshkey/testdata/dsa_n_pw] [regress/unittests/sshkey/testdata/ecdsa_1] [regress/unittests/sshkey/testdata/ecdsa_1-cert.fp] [regress/unittests/sshkey/testdata/ecdsa_1-cert.pub] [regress/unittests/sshkey/testdata/ecdsa_1.fp] [regress/unittests/sshkey/testdata/ecdsa_1.fp.bb] [regress/unittests/sshkey/testdata/ecdsa_1.param.curve] [regress/unittests/sshkey/testdata/ecdsa_1.param.priv] [regress/unittests/sshkey/testdata/ecdsa_1.param.pub] [regress/unittests/sshkey/testdata/ecdsa_1.pub] [regress/unittests/sshkey/testdata/ecdsa_1_pw] [regress/unittests/sshkey/testdata/ecdsa_2] [regress/unittests/sshkey/testdata/ecdsa_2.fp] [regress/unittests/sshkey/testdata/ecdsa_2.fp.bb] [regress/unittests/sshkey/testdata/ecdsa_2.param.curve] [regress/unittests/sshkey/testdata/ecdsa_2.param.priv] [regress/unittests/sshkey/testdata/ecdsa_2.param.pub] [regress/unittests/sshkey/testdata/ecdsa_2.pub] [regress/unittests/sshkey/testdata/ecdsa_n] [regress/unittests/sshkey/testdata/ecdsa_n_pw] [regress/unittests/sshkey/testdata/ed25519_1] [regress/unittests/sshkey/testdata/ed25519_1-cert.fp] [regress/unittests/sshkey/testdata/ed25519_1-cert.pub] [regress/unittests/sshkey/testdata/ed25519_1.fp] [regress/unittests/sshkey/testdata/ed25519_1.fp.bb] [regress/unittests/sshkey/testdata/ed25519_1.pub] [regress/unittests/sshkey/testdata/ed25519_1_pw] [regress/unittests/sshkey/testdata/ed25519_2] [regress/unittests/sshkey/testdata/ed25519_2.fp] [regress/unittests/sshkey/testdata/ed25519_2.fp.bb] [regress/unittests/sshkey/testdata/ed25519_2.pub] [regress/unittests/sshkey/testdata/pw] [regress/unittests/sshkey/testdata/rsa1_1] [regress/unittests/sshkey/testdata/rsa1_1.fp] [regress/unittests/sshkey/testdata/rsa1_1.fp.bb] [regress/unittests/sshkey/testdata/rsa1_1.param.n] [regress/unittests/sshkey/testdata/rsa1_1.pub] [regress/unittests/sshkey/testdata/rsa1_1_pw] [regress/unittests/sshkey/testdata/rsa1_2] [regress/unittests/sshkey/testdata/rsa1_2.fp] [regress/unittests/sshkey/testdata/rsa1_2.fp.bb] [regress/unittests/sshkey/testdata/rsa1_2.param.n] [regress/unittests/sshkey/testdata/rsa1_2.pub] [regress/unittests/sshkey/testdata/rsa_1] [regress/unittests/sshkey/testdata/rsa_1-cert.fp] [regress/unittests/sshkey/testdata/rsa_1-cert.pub] [regress/unittests/sshkey/testdata/rsa_1.fp] [regress/unittests/sshkey/testdata/rsa_1.fp.bb] [regress/unittests/sshkey/testdata/rsa_1.param.n] [regress/unittests/sshkey/testdata/rsa_1.param.p] [regress/unittests/sshkey/testdata/rsa_1.param.q] [regress/unittests/sshkey/testdata/rsa_1.pub] [regress/unittests/sshkey/testdata/rsa_1_pw] [regress/unittests/sshkey/testdata/rsa_2] [regress/unittests/sshkey/testdata/rsa_2.fp] [regress/unittests/sshkey/testdata/rsa_2.fp.bb] [regress/unittests/sshkey/testdata/rsa_2.param.n] [regress/unittests/sshkey/testdata/rsa_2.param.p] [regress/unittests/sshkey/testdata/rsa_2.param.q] [regress/unittests/sshkey/testdata/rsa_2.pub] [regress/unittests/sshkey/testdata/rsa_n] [regress/unittests/sshkey/testdata/rsa_n_pw] unit and fuzz tests for new key API commit c1dc24b71f087f385b92652b9673f52af64e0428 Author: Damien Miller Date: Wed Jul 2 17:02:03 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 01:04:43 [regress/krl.sh] regress test for broken consecutive revoked serial number ranges commit 43d3ed2dd3feca6d0326c7dc82588d2faa115e92 Author: Damien Miller Date: Wed Jul 2 17:01:08 2014 +1000 - djm@cvs.openbsd.org 2014/05/21 07:04:21 [regress/integrity.sh] when failing because of unexpected output, show the offending output commit 5a96707ffc8d227c2e7d94fa6b0317f8a152cf4e Author: Damien Miller Date: Wed Jul 2 15:38:05 2014 +1000 - djm@cvs.openbsd.org 2014/04/30 05:32:00 [regress/Makefile] unit tests for new buffer API; including basic fuzz testing NB. Id sync only. commit 3ff92ba756aee48e4ae3e0aeff7293517b3dd185 Author: Damien Miller Date: Wed Jul 2 15:33:09 2014 +1000 - djm@cvs.openbsd.org 2014/06/30 12:54:39 [key.c] suppress spurious error message when loading key with a passphrase; reported by kettenis@ ok markus@ - djm@cvs.openbsd.org 2014/07/02 04:59:06 [cipher-3des1.c] fix ssh protocol 1 on the server that regressed with the sshkey change (sometimes fatal() after auth completed), make file return useful status codes. NB. Id sync only for these two. They were bundled into the sshkey merge above, since it was easier to sync the entire file and then apply portable-specific changed atop it. commit ec3d0e24a1e46873d80507f5cd8ee6d0d03ac5dc Author: Damien Miller Date: Wed Jul 2 15:30:00 2014 +1000 - markus@cvs.openbsd.org 2014/06/27 18:50:39 [ssh-add.c] fix loading of private keys commit 4b3ed647d5b328cf68e6a8ffbee490d8e0683e82 Author: Damien Miller Date: Wed Jul 2 15:29:40 2014 +1000 - markus@cvs.openbsd.org 2014/06/27 16:41:56 [channels.c channels.h clientloop.c ssh.c] fix remote fwding with same listen port but different listen address with gerhard@, ok djm@ commit 9e01ff28664921ce9b6500681333e42fb133b4d0 Author: Damien Miller Date: Wed Jul 2 15:29:21 2014 +1000 - deraadt@cvs.openbsd.org 2014/06/25 14:16:09 [sshbuf.c] unblock SIGSEGV before raising it ok djm commit 1845fe6bda0729e52f4c645137f4fc3070b5438a Author: Damien Miller Date: Wed Jul 2 15:29:01 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 02:21:01 [scp.c] when copying local->remote fails during read, don't send uninitialised heap to the remote end. Reported by Jann Horn commit 19439e9a2a0ac0b4b3b1210e89695418beb1c883 Author: Damien Miller Date: Wed Jul 2 15:28:40 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 02:19:48 [ssh.c] don't fatal() when hostname canonicalisation fails with a ProxyCommand in use; continue and allow the ProxyCommand to connect anyway (e.g. to a host with a name outside the DNS behind a bastion) commit 8668706d0f52654fe64c0ca41a96113aeab8d2b8 Author: Damien Miller Date: Wed Jul 2 15:28:02 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 01:13:21 [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c [sshconnect2.c sshd.c sshkey.c sshkey.h [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h] New key API: refactor key-related functions to be more library-like, existing API is offered as a set of wrappers. with and ok markus@ Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew Dempsky and Ron Bowes for a detailed review a few months ago. NB. This commit also removes portable OpenSSH support for OpenSSL <0.9.8e. commit 2cd7929250cf9e9f658d70dcd452f529ba08c942 Author: Damien Miller Date: Wed Jul 2 12:48:30 2014 +1000 - djm@cvs.openbsd.org 2014/06/24 00:52:02 [krl.c] fix bug in KRL generation: multiple consecutive revoked certificate serial number ranges could be serialised to an invalid format. Readers of a broken KRL caused by this bug will fail closed, so no should-have-been-revoked key will be accepted. commit 99db840ee8dbbd2b3fbc6c45d0ee2f6a65e96898 Author: Damien Miller Date: Wed Jul 2 12:48:04 2014 +1000 - naddy@cvs.openbsd.org 2014/06/18 15:42:09 [sshbuf-getput-crypto.c] The ssh_get_bignum functions must accept the same range of bignums the corresponding ssh_put_bignum functions create. This fixes the use of 16384-bit RSA keys (bug reported by Eivind Evensen). ok djm@ commit 84a89161a9629239b64171ef3e22ef6a3e462d51 Author: Damien Miller Date: Wed Jul 2 12:47:48 2014 +1000 - matthew@cvs.openbsd.org 2014/06/18 02:59:13 [sandbox-systrace.c] Now that we have a dedicated getentropy(2) system call for arc4random(3), we can disallow __sysctl(2) in OpenSSH's systrace sandbox. ok djm commit 51504ceec627c0ad57b9f75585c7b3d277f326be Author: Damien Miller Date: Wed Jul 2 12:47:25 2014 +1000 - deraadt@cvs.openbsd.org 2014/06/13 08:26:29 [sandbox-systrace.c] permit SYS_getentropy from matthew commit a261b8df59117f7dc52abb3a34b35a40c2c9fa88 Author: Tim Rice Date: Wed Jun 18 16:17:28 2014 -0700 - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare commit 316fac6f18f87262a315c79bcf68b9f92c9337e4 Author: Darren Tucker Date: Tue Jun 17 23:06:07 2014 +1000 - (dtucker) [entropy.c openbsd-compat/openssl-compat.{c,h} openbsd-compat/regress/{.cvsignore,Makefile.in,opensslvertest.c}] Move the OpenSSL header/library version test into its own function and add tests for it. Fix it to allow fix version upgrades (but not downgrades). Prompted by chl@ via OpenSMTPD (issue #462) and Debian (bug #748150). ok djm@ chl@ commit af665bb7b092a59104db1e65577851cf35b86e32 Author: Darren Tucker Date: Mon Jun 16 22:50:55 2014 +1000 - (dtucker) [defines.h] Fix undef of _PATH_MAILDIR. From rak at debian via OpenSMTPD and chl@ commit f9696566fb41320820f3b257ab564fa321bb3751 Author: Darren Tucker Date: Fri Jun 13 11:06:04 2014 +1000 - (dtucker) [configure.ac] Remove tcpwrappers support, support has already been removed from sshd.c. commit 5e2b8894b0b24af4ad0a2f7aa33ebf255df7a8bc Author: Tim Rice Date: Wed Jun 11 18:31:10 2014 -0700 - (tim) [regress/unittests/test_helper/test_helper.h] Add includes.h for u_intXX_t types. commit 985ee2cbc3e43bc65827c3c0d4df3faa99160c37 Author: Darren Tucker Date: Thu Jun 12 05:32:29 2014 +1000 - (dtucker) [regress/unittests/sshbuf/*.c regress/unittests/test_helper/*] Wrap stdlib.h include an ifdef for platforms that don't have it. commit cf5392c2db2bb1dbef9818511d34056404436109 Author: Darren Tucker Date: Thu Jun 12 05:22:49 2014 +1000 - (dtucker) [defines.h] Add va_copy if we don't already have it, taken from openbsd-compat/bsd-asprintf.c. commit 58538d795e0b662f2f4e5a7193f1204bbe992ddd Author: Darren Tucker Date: Wed Jun 11 13:39:24 2014 +1000 - (dtucker) [bufaux.c bufbn.c bufec.c buffer.c] Pull in includes.h for compat stuff, specifically whether or not OpenSSL has ECC. commit eb012ac581fd0abc16ee86ee3a68cf07c8ce4d08 Author: Darren Tucker Date: Wed Jun 11 13:10:00 2014 +1000 - (dtucker) [openbsd-compat/arc4random.c] Use explicit_bzero instead of an assigment that might get optimized out. ok djm@ commit b9609fd86c623d6d440e630f5f9a63295f7aea20 Author: Darren Tucker Date: Wed Jun 11 08:04:02 2014 +1000 - (dtucker) [sshbuf.h] Only declare ECC functions if building without OpenSSL or if OpenSSL has ECC. commit a54a040f66944c6e8913df8635a01a2327219be9 Author: Darren Tucker Date: Wed Jun 11 07:58:35 2014 +1000 - dtucker@cvs.openbsd.org 2014/06/10 21:46:11 [sshbuf.h] Group ECC functions together to make things a little easier in -portable. "doesn't bother me" deraadt@ commit 9f92c53bad04a89067756be8198d4ec2d8a08875 Author: Darren Tucker Date: Wed Jun 11 07:57:58 2014 +1000 - djm@cvs.openbsd.org 2014/06/05 22:17:50 [sshconnect2.c] fix inverted test that caused PKCS#11 keys that were explicitly listed not to be preferred. Reported by Dirk-Willem van Gulik commit 15c254a25394f96643da2ad0f674acdc51e89856 Author: Darren Tucker Date: Wed Jun 11 07:38:49 2014 +1000 - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] ifdef ECC variable too. commit d7af0cc5bf273eeed0897a99420bc26841d07d8f Author: Darren Tucker Date: Wed Jun 11 07:37:25 2014 +1000 - (dtucker) [myprosal.h] Don't include curve25519-sha256@libssh.org in the proposal if the version of OpenSSL we're using doesn't support ECC. commit 67508ac2563c33d582be181a3e777c65f549d22f Author: Darren Tucker Date: Wed Jun 11 06:27:16 2014 +1000 - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] Only do NISTP256 curve tests if OpenSSL has them. commit 6482d90a65459a88c18c925368525855832272b3 Author: Damien Miller Date: Tue May 27 14:34:42 2014 +1000 - (djm) [configure.ac openbsd-compat/bsd-cygwin_util.c] [openbsd-compat/bsd-cygwin_util.h] On Cygwin, determine privilege separation user at runtime, since it may need to be a domain account. Patch from Corinna Vinschen. commit f9eb5e0734f7a7f6e975809eb54684d2a06a7ffc Author: Damien Miller Date: Tue May 27 14:31:58 2014 +1000 - (djm) [contrib/cygwin/ssh-host-config] Updated Cygwin ssh-host-config from Corinna Vinschen, fixing a number of bugs and preparing for Cygwin 1.7.30. commit eae88744662e6b149f43ef071657727f1a157d95 Author: Damien Miller Date: Tue May 27 14:27:02 2014 +1000 - (djm) [cipher.c] Fix merge botch. commit 564b5e253c1d95c26a00e8288f0089a2571661c3 Author: Damien Miller Date: Thu May 22 08:23:59 2014 +1000 - (djm) [Makefile.in] typo in path commit e84d10302aeaf7a1acb05c451f8718143656856a Author: Damien Miller Date: Wed May 21 17:13:36 2014 +1000 revert a diff I didn't mean to commit commit 795b86313f1f1aab9691666c4f2d5dae6e4acd50 Author: Damien Miller Date: Wed May 21 17:12:53 2014 +1000 - (djm) [misc.c] Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It takes into account time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly. bz#2228 reported by John Haxby commit 18912775cb97c0b1e75e838d3c7d4b56648137b5 Author: Damien Miller Date: Wed May 21 17:06:46 2014 +1000 - (djm) [commit configure.ac defines.h sshpty.c] don't attempt to use vhangup on Linux. It doens't work for non-root users, and for them it just messes up the tty settings. commit 7f1c264d3049cd95234e91970ccb5406e1d15b27 Author: Damien Miller Date: Thu May 15 18:01:52 2014 +1000 - (djm) [sshbuf.c] need __predict_false commit e7429f2be8643e1100380a8a7389d85cc286c8fe Author: Damien Miller Date: Thu May 15 18:01:01 2014 +1000 - (djm) [regress/Makefile Makefile.in] [regress/unittests/sshbuf/test_sshbuf.c [regress/unittests/sshbuf/test_sshbuf_fixed.c] [regress/unittests/sshbuf/test_sshbuf_fuzz.c] [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] [regress/unittests/sshbuf/test_sshbuf_misc.c] [regress/unittests/sshbuf/tests.c] [regress/unittests/test_helper/fuzz.c] [regress/unittests/test_helper/test_helper.c] Hook new unit tests into the build and "make tests" commit def1de086707b0e6b046fe7e115c60aca0227a99 Author: Damien Miller Date: Thu May 15 15:17:15 2014 +1000 - (djm) [regress/unittests/Makefile] [regress/unittests/Makefile.inc] [regress/unittests/sshbuf/Makefile] [regress/unittests/sshbuf/test_sshbuf.c] [regress/unittests/sshbuf/test_sshbuf_fixed.c] [regress/unittests/sshbuf/test_sshbuf_fuzz.c] [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] [regress/unittests/sshbuf/test_sshbuf_misc.c] [regress/unittests/sshbuf/tests.c] [regress/unittests/test_helper/Makefile] [regress/unittests/test_helper/fuzz.c] [regress/unittests/test_helper/test_helper.c] [regress/unittests/test_helper/test_helper.h] Import new unit tests from OpenBSD; not yet hooked up to build. commit 167685756fde8bc213a8df2c8e1848e312db0f46 Author: Damien Miller Date: Thu May 15 15:08:40 2014 +1000 - logan@cvs.openbsd.org 2014/05/04 10:40:59 [connect-privsep.sh] Remove the Z flag from the list of malloc options as it was removed from malloc.c 10 days ago. OK from miod@ commit d0b69fe90466920d69c96069312e24b581771bd7 Author: Damien Miller Date: Thu May 15 15:08:19 2014 +1000 - dtucker@cvs.openbsd.org 2014/05/03 18:46:14 [proxy-connect.sh] Add tests for with and without compression, with and without privsep. commit edb1af50441d19fb2dd9ccb4d75bf14473fca584 Author: Damien Miller Date: Thu May 15 15:07:53 2014 +1000 - djm@cvs.openbsd.org 2014/04/21 22:15:37 [dhgex.sh integrity.sh kextype.sh rekey.sh try-ciphers.sh] repair regress tests broken by server-side default cipher/kex/mac changes by ensuring that the option under test is included in the server's algorithm list commit 54343e95c70994695f8842fb22836321350198d3 Author: Damien Miller Date: Thu May 15 15:07:33 2014 +1000 - djm@cvs.openbsd.org 2014/03/13 20:44:49 [login-timeout.sh] this test is a sorry mess of race conditions; add another sleep to avoid a failure on slow machines (at least until I find a better way) commit e5b9f0f2ee6e133894307e44e862b66426990733 Author: Damien Miller Date: Thu May 15 14:58:07 2014 +1000 - (djm) [Makefile.in configure.ac sshbuf-getput-basic.c] [sshbuf-getput-crypto.c sshbuf.c] compilation and portability fixes commit b9c566788a9ebd6a9d466f47a532124f111f0542 Author: Damien Miller Date: Thu May 15 14:43:37 2014 +1000 - (djm) [configure.ac] Unconditionally define WITH_OPENSSL until we write portability glue to support building without libcrypto commit 3dc27178b42234b653a32f7a87292d7994045ee3 Author: Damien Miller Date: Thu May 15 14:37:59 2014 +1000 - logan@cvs.openbsd.org 2014/05/05 07:02:30 [sftp.c] Zap extra whitespace. OK from djm@ and dtucker@ commit c31a0cd5b31961f01c5b731f62a6cb9d4f767472 Author: Damien Miller Date: Thu May 15 14:37:39 2014 +1000 - markus@cvs.openbsd.org 2014/05/03 17:20:34 [monitor.c packet.c packet.h] unbreak compression, by re-init-ing the compression code in the post-auth child. the new buffer code is more strict, and requires buffer_init() while the old code was happy after a bzero(); originally from djm@ commit 686c7d9ee6f44b2be4128d7860b6b37adaeba733 Author: Damien Miller Date: Thu May 15 14:37:03 2014 +1000 - djm@cvs.openbsd.org 2014/05/02 03:27:54 [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c] [misc.h poly1305.h ssh-pkcs11.c defines.h] revert __bounded change; it causes way more problems for portable than it solves; pointed out by dtucker@ commit 294c58a007cfb2f3bddc4fc3217e255857ffb9bf Author: Damien Miller Date: Thu May 15 14:35:03 2014 +1000 - naddy@cvs.openbsd.org 2014/04/30 19:07:48 [mac.c myproposal.h umac.c] UMAC can use our local fallback implementation of AES when OpenSSL isn't available. Glue code straight from Ted Krovetz's original umac.c. ok markus@ commit 05e82c3b963c33048128baf72a6f6b3a1c10b4c1 Author: Damien Miller Date: Thu May 15 14:33:43 2014 +1000 - djm@cvs.openbsd.org 2014/04/30 05:29:56 [bufaux.c bufbn.c bufec.c buffer.c buffer.h sshbuf-getput-basic.c] [sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c sshbuf.h ssherr.c] [ssherr.h] New buffer API; the first installment of the conversion/replacement of OpenSSH's internals to make them usable as a standalone library. This includes a set of wrappers to make it compatible with the existing buffer API so replacement can occur incrementally. With and ok markus@ Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew Dempsky and Ron Bowes for a detailed review. commit 380948180f847a26f2d0c85b4dad3dca2ed2fd8b Author: Damien Miller Date: Thu May 15 14:25:18 2014 +1000 - dtucker@cvs.openbsd.org 2014/04/29 20:36:51 [sftp.c] Don't attempt to append a nul quote char to the filename. Should prevent fatal'ing with "el_insertstr failed" when there's a single quote char somewhere in the string. bz#2238, ok markus@ commit d7fd8bedd4619a2ec7fd02aae4c4e1db4431ad9f Author: Damien Miller Date: Thu May 15 14:24:59 2014 +1000 - dtucker@cvs.openbsd.org 2014/04/29 19:58:50 [sftp.c] Move nulling of variable next to where it's freed. ok markus@ commit 1f0311c7c7d10c94ff7f823de9c5b2ed79368b14 Author: Damien Miller Date: Thu May 15 14:24:09 2014 +1000 - markus@cvs.openbsd.org 2014/04/29 18:01:49 [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c] [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c] [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c] make compiling against OpenSSL optional (make OPENSSL=no); reduces algorithms to curve25519, aes-ctr, chacha, ed25519; allows us to explore further options; with and ok djm commit c5893785564498cea73cb60d2cf199490483e080 Author: Damien Miller Date: Thu May 15 13:48:49 2014 +1000 - djm@cvs.openbsd.org 2014/04/29 13:10:30 [clientloop.c serverloop.c] bz#1818 - don't send channel success/failre replies on channels that have sent a close already; analysis and patch from Simon Tatham; ok markus@ commit 633de33b192d808d87537834c316dc8b75fe1880 Author: Damien Miller Date: Thu May 15 13:48:26 2014 +1000 - djm@cvs.openbsd.org 2014/04/28 03:09:18 [authfile.c bufaux.c buffer.h channels.c krl.c mux.c packet.c packet.h] [ssh-keygen.c] buffer_get_string_ptr's return should be const to remind callers that futzing with it will futz with the actual buffer contents commit 15271907843e4ae50dcfc83b3594014cf5e9607b Author: Damien Miller Date: Thu May 15 13:47:56 2014 +1000 - djm@cvs.openbsd.org 2014/04/23 12:42:34 [readconf.c] don't record duplicate IdentityFiles commit 798a02568b13a2e46efebd81f08c8f4bb33a6dc7 Author: Damien Miller Date: Thu May 15 13:47:37 2014 +1000 - jmc@cvs.openbsd.org 2014/04/22 14:16:30 [sftp.1] zap eol whitespace; commit d875ff78d2b8436807381051de112f0ebf9b9ae1 Author: Damien Miller Date: Thu May 15 13:47:15 2014 +1000 - logan@cvs.openbsd.org 2014/04/22 12:42:04 [sftp.1] Document sftp upload resume. OK from djm@, with feedback from okan@. commit b15cd7bb097fd80dc99520f45290ef775da1ef19 Author: Damien Miller Date: Thu May 15 13:46:52 2014 +1000 - logan@cvs.openbsd.org 2014/04/22 10:07:12 [sftp.c] Sort the sftp command list. OK from djm@ commit d8accc0aa72656ba63d50937165c5ae49db1dcd6 Author: Damien Miller Date: Thu May 15 13:46:25 2014 +1000 - logan@cvs.openbsd.org 2014/04/21 14:36:16 [sftp-client.c sftp-client.h sftp.c] Implement sftp upload resume support. OK from djm@, with input from guenther@, mlarkin@ and okan@ commit 16cd3928a87d20c77b13592a74b60b08621d3ce6 Author: Damien Miller Date: Thu May 15 13:45:58 2014 +1000 - logan@cvs.openbsd.org 2014/04/20 09:24:26 [dns.c dns.h ssh-keygen.c] Add support for SSHFP DNS records for ED25519 key types. OK from djm@ commit ec0b67eb3b4e12f296ced1fafa01860c374f7eea Author: Damien Miller Date: Thu May 15 13:45:26 2014 +1000 - (djm) [rijndael.c rijndael.h] Sync with newly-ressurected versions ine OpenBSD commit f028460d0b2e5a584355321015cde69bf6fd933e Author: Darren Tucker Date: Thu May 1 02:24:35 2014 +1000 - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already have it. Only attempt to use __attribute__(__bounded__) for gcc. commit b628cc4c3e4a842bab5e4584d18c2bc5fa4d0edf Author: Damien Miller Date: Sun Apr 20 13:33:58 2014 +1000 - djm@cvs.openbsd.org 2014/04/20 02:49:32 [compat.c] add a canonical 6.6 + curve25519 bignum fix fake version that I can recommend people use ahead of the openssh-6.7 release commit 888566913933a802f3a329ace123ebcb7154cf78 Author: Damien Miller Date: Sun Apr 20 13:33:19 2014 +1000 - djm@cvs.openbsd.org 2014/04/20 02:30:25 [misc.c misc.h umac.c] use get/put_u32 to load values rather than *((UINT32 *)p) that breaks on strict-alignment architectures; reported by and ok stsp@ commit 16f85cbc7e5139950e6a38317e7c8b368beafa5d Author: Damien Miller Date: Sun Apr 20 13:29:28 2014 +1000 - tedu@cvs.openbsd.org 2014/04/19 18:42:19 [ssh.1] delete .xr to hosts.equiv. there's still an unfortunate amount of documentation referring to rhosts equivalency in here. commit 69cb24b7356ec3f0fc5ff04a68f98f2c55c766f4 Author: Damien Miller Date: Sun Apr 20 13:29:06 2014 +1000 - tedu@cvs.openbsd.org 2014/04/19 18:15:16 [sshd.8] remove some really old rsh references commit 84c1e7bca8c4ceaccf4d5557e39a833585a3c77e Author: Damien Miller Date: Sun Apr 20 13:27:53 2014 +1000 - tedu@cvs.openbsd.org 2014/04/19 14:53:48 [ssh-keysign.c sshd.c] Delete futile calls to RAND_seed. ok djm NB. Id sync only. This only applies to OpenBSD's libcrypto slashathon commit 0e6b67423b8662f9ca4c92750309e144fd637ef1 Author: Damien Miller Date: Sun Apr 20 13:27:01 2014 +1000 - djm@cvs.openbsd.org 2014/04/19 05:54:59 [compat.c] missing wildcard; pointed out by naddy@ commit 9395b28223334826837c15e8c1bb4dfb3b0d2ca5 Author: Damien Miller Date: Sun Apr 20 13:25:30 2014 +1000 - djm@cvs.openbsd.org 2014/04/18 23:52:25 [compat.c compat.h sshconnect2.c sshd.c version.h] OpenSSH 6.5 and 6.6 have a bug that causes ~0.2% of connections using the curve25519-sha256@libssh.org KEX exchange method to fail when connecting with something that implements the spec properly. Disable this KEX method when speaking to one of the affected versions. reported by Aris Adamantiadis; ok markus@ commit 8c492da58f8ceb85cf5f7066f23e26fb813a963d Author: Damien Miller Date: Sun Apr 20 13:25:09 2014 +1000 - djm@cvs.openbsd.org 2014/04/16 23:28:12 [ssh-agent.1] remove the identity files from this manpage - ssh-agent doesn't deal with them at all and the same information is duplicated in ssh-add.1 (which does deal with them); prodded by deraadt@ commit adbfdbbdccc70c9bd70d81ae096db115445c6e26 Author: Damien Miller Date: Sun Apr 20 13:24:49 2014 +1000 - djm@cvs.openbsd.org 2014/04/16 23:22:45 [bufaux.c] skip leading zero bytes in buffer_put_bignum2_from_string(); reported by jan AT mojzis.com; ok markus@ commit 75c62728dc87af6805696eeb520b9748faa136c8 Author: Damien Miller Date: Sun Apr 20 13:24:31 2014 +1000 - djm@cvs.openbsd.org 2014/04/12 04:55:53 [sshd.c] avoid crash at exit: check that pmonitor!=NULL before dereferencing; bz#2225, patch from kavi AT juniper.net commit 2a328437fb1b0976f2f4522d8645803d5a5d0967 Author: Damien Miller Date: Sun Apr 20 13:24:01 2014 +1000 - djm@cvs.openbsd.org 2014/04/01 05:32:57 [packet.c] demote a debug3 to PACKET_DEBUG; ok markus@ commit 7d6a9fb660c808882d064e152d6070ffc3844c3f Author: Damien Miller Date: Sun Apr 20 13:23:43 2014 +1000 - djm@cvs.openbsd.org 2014/04/01 03:34:10 [sshconnect.c] When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any certificate keys to plain keys and attempt SSHFP resolution. Prevents a server from skipping SSHFP lookup and forcing a new-hostkey dialog by offering only certificate keys. Reported by mcv21 AT cam.ac.uk commit fcd62c0b66b8415405ed0af29c236329eb88cc0f Author: Damien Miller Date: Sun Apr 20 13:23:21 2014 +1000 - djm@cvs.openbsd.org 2014/04/01 02:05:27 [ssh-keysign.c] include fingerprint of key not found use arc4random_buf() instead of loop+arc4random() commit 43b156cf72f900f88065b0a1c1ebd09ab733ca46 Author: Damien Miller Date: Sun Apr 20 13:23:03 2014 +1000 - jmc@cvs.openbsd.org 2014/03/31 13:39:34 [ssh-keygen.1] the text for the -K option was inserted in the wrong place in -r1.108; fix From: Matthew Clarke commit c1621c84f2dc1279065ab9fde2aa9327af418900 Author: Damien Miller Date: Sun Apr 20 13:22:46 2014 +1000 - naddy@cvs.openbsd.org 2014/03/28 05:17:11 [ssh_config.5 sshd_config.5] sync available and default algorithms, improve algorithm list formatting help from jmc@ and schwarze@, ok deraadt@ commit f2719b7c2b8a3b14d778d8a6d8dc729b5174b054 Author: Damien Miller Date: Sun Apr 20 13:22:18 2014 +1000 - tedu@cvs.openbsd.org 2014/03/26 19:58:37 [sshd.8 sshd.c] remove libwrap support. ok deraadt djm mfriedl commit 4f40209aa4060b9c066a2f0d9332ace7b8dfb391 Author: Damien Miller Date: Sun Apr 20 13:21:22 2014 +1000 - djm@cvs.openbsd.org 2014/03/26 04:55:35 [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c [misc.h poly1305.h ssh-pkcs11.c] use __bounded(...) attribute recently added to sys/cdefs.h instead of longform __attribute__(__bounded(...)); for brevity and a warning free compilation with llvm/clang commit 9235a030ad1b16903fb495d81544e0f7c7449523 Author: Damien Miller Date: Sun Apr 20 13:17:20 2014 +1000 Three commits in one (since they touch the same heavily-diverged file repeatedly): - markus@cvs.openbsd.org 2014/03/25 09:40:03 [myproposal.h] trimm default proposals. This commit removes the weaker pre-SHA2 hashes, the broken ciphers (arcfour), and the broken modes (CBC) from the default configuration (the patch only changes the default, all the modes are still available for the config files). ok djm@, reminded by tedu@ & naddy@ and discussed with many - deraadt@cvs.openbsd.org 2014/03/26 17:16:26 [myproposal.h] The current sharing of myproposal[] between both client and server code makes the previous diff highly unpallatable. We want to go in that direction for the server, but not for the client. Sigh. Brought up by naddy. - markus@cvs.openbsd.org 2014/03/27 23:01:27 [myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] disable weak proposals in sshd, but keep them in ssh; ok djm@ commit 6e1777f592f15f4559728c78204617537b1ac076 Author: Damien Miller Date: Sun Apr 20 13:02:58 2014 +1000 - tedu@cvs.openbsd.org 2014/03/19 14:42:44 [scp.1] there is no need for rcp anymore ok deraadt millert commit eb1b7c514d2a7b1802ccee8cd50e565a4d419887 Author: Damien Miller Date: Sun Apr 20 13:02:26 2014 +1000 - tedu@cvs.openbsd.org 2014/03/17 19:44:10 [ssh.1] old descriptions of des and blowfish are old. maybe ok deraadt commit f0858de6e1324ec730752387074b111b8551081e Author: Damien Miller Date: Sun Apr 20 13:01:30 2014 +1000 - deraadt@cvs.openbsd.org 2014/03/15 17:28:26 [ssh-agent.c ssh-keygen.1 ssh-keygen.c] Improve usage() and documentation towards the standard form. In particular, this line saves a lot of man page reading time. usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] [-N new_passphrase] [-C comment] [-f output_keyfile] ok schwarze jmc commit 94bfe0fbd6e91a56b5b0ab94ac955d2a67d101aa Author: Damien Miller Date: Sun Apr 20 13:00:51 2014 +1000 - naddy@cvs.openbsd.org 2014/03/12 13:06:59 [ssh-keyscan.1] scan for Ed25519 keys by default too commit 3819519288b2b3928c6882f5883b0f55148f4fc0 Author: Damien Miller Date: Sun Apr 20 13:00:28 2014 +1000 - djm@cvs.openbsd.org 2014/03/12 04:51:12 [authfile.c] correct test that kdf name is not "none" or "bcrypt" commit 8f9cd709c7cf0655d414306a0ed28306b33802be Author: Damien Miller Date: Sun Apr 20 13:00:11 2014 +1000 - djm@cvs.openbsd.org 2014/03/12 04:50:32 [auth-bsdauth.c ssh-keygen.c] don't count on things that accept arguments by reference to clear things for us on error; most things do, but it's unsafe form. commit 1c7ef4be83f6dec84509a312518b9df00ab491d9 Author: Damien Miller Date: Sun Apr 20 12:59:46 2014 +1000 - djm@cvs.openbsd.org 2014/03/12 04:44:58 [ssh-keyscan.c] scan for Ed25519 keys by default too commit c10bf4d051c97939b30a1616c0499310057d07da Author: Damien Miller Date: Sun Apr 20 12:58:04 2014 +1000 - djm@cvs.openbsd.org 2014/03/03 22:22:30 [session.c] ignore enviornment variables with embedded '=' or '\0' characters; spotted by Jann Horn; ok deraadt@ Id sync only - portable already has this. commit c2e49062faccbcd7135c40d1c78c5c329c58fc2e Author: Damien Miller Date: Tue Apr 1 14:42:46 2014 +1100 - (djm) Use full release (e.g. 6.5p1) in debug output rather than just version. From des@des.no commit 14928b7492abec82afa4c2b778fc03f78cd419b6 Author: Damien Miller Date: Tue Apr 1 14:38:07 2014 +1100 - (djm) On platforms that support it, use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}; patch from jann AT thejh.net commit 48abc47e60048461fe9117e108a7e99ea1ac2bb8 Author: Damien Miller Date: Mon Mar 17 14:45:56 2014 +1100 - (djm) [sandbox-seccomp-filter.c] Soft-fail stat() syscalls. Add XXX to remind myself to add sandbox violation logging via the log socket. commit 9c36698ca2f554ec221dc7ef29c7a89e97c88705 Author: Tim Rice Date: Fri Mar 14 12:45:01 2014 -0700 20140314 - (tim) [opensshd.init.in] Add support for ed25519 commit 19158b2447e35838d69b2b735fb640d1e86061ea Author: Damien Miller Date: Thu Mar 13 13:14:21 2014 +1100 - (djm) Release OpenSSH 6.6 openssh-7.2p2/moduli.0010064400017500001750000000065661267007032700130450ustar00djmdjmMODULI(5) File Formats Manual MODULI(5) NAME moduli M-bM-^@M-^S Diffie-Hellman moduli DESCRIPTION The /etc/moduli file contains prime numbers and generators for use by sshd(8) in the Diffie-Hellman Group Exchange key exchange method. New moduli may be generated with ssh-keygen(1) using a two-step process. An initial candidate generation pass, using ssh-keygen -G, calculates numbers that are likely to be useful. A second primality testing pass, using ssh-keygen -T, provides a high degree of assurance that the numbers are prime and are safe for use in Diffie-Hellman operations by sshd(8). This moduli format is used as the output from each pass. The file consists of newline-separated records, one per modulus, containing seven space-separated fields. These fields are as follows: timestamp The time that the modulus was last processed as YYYYMMDDHHMMSS. type Decimal number specifying the internal structure of the prime modulus. Supported types are: 0 Unknown, not tested. 2 "Safe" prime; (p-1)/2 is also prime. 4 Sophie Germain; 2p+1 is also prime. Moduli candidates initially produced by ssh-keygen(1) are Sophie Germain primes (type 4). Further primality testing with ssh-keygen(1) produces safe prime moduli (type 2) that are ready for use in sshd(8). Other types are not used by OpenSSH. tests Decimal number indicating the type of primality tests that the number has been subjected to represented as a bitmask of the following values: 0x00 Not tested. 0x01 Composite number M-bM-^@M-^S not prime. 0x02 Sieve of Eratosthenes. 0x04 Probabilistic Miller-Rabin primality tests. The ssh-keygen(1) moduli candidate generation uses the Sieve of Eratosthenes (flag 0x02). Subsequent ssh-keygen(1) primality tests are Miller-Rabin tests (flag 0x04). trials Decimal number indicating the number of primality trials that have been performed on the modulus. size Decimal number indicating the size of the prime in bits. generator The recommended generator for use with this modulus (hexadecimal). modulus The modulus itself in hexadecimal. When performing Diffie-Hellman Group Exchange, sshd(8) first estimates the size of the modulus required to produce enough Diffie-Hellman output to sufficiently key the selected symmetric cipher. sshd(8) then randomly selects a modulus from /etc/moduli that best meets the size requirement. SEE ALSO ssh-keygen(1), sshd(8) STANDARDS M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, 2006. OpenBSD 5.9 September 26, 2012 OpenBSD 5.9 openssh-7.2p2/scp.0010064400017500001750000000140321267007032700123240ustar00djmdjmSCP(1) General Commands Manual SCP(1) NAME scp M-bM-^@M-^S secure copy (remote file copy program) SYNOPSIS scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-S program] [[user@]host1:]file1 ... [[user@]host2:]file2 DESCRIPTION scp copies files between hosts on a network. It uses ssh(1) for data transfer, and uses the same authentication and provides the same security as ssh(1). scp will ask for passwords or passphrases if they are needed for authentication. File names may contain a user and host specification to indicate that the file is to be copied to/from that host. Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file names containing M-bM-^@M-^X:M-bM-^@M-^Y as host specifiers. Copies between two remote hosts are also permitted. The options are as follows: -1 Forces scp to use protocol 1. -2 Forces scp to use protocol 2. -3 Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts. Note that this option disables the progress meter. -4 Forces scp to use IPv4 addresses only. -6 Forces scp to use IPv6 addresses only. -B Selects batch mode (prevents asking for passwords or passphrases). -C Compression enable. Passes the -C flag to ssh(1) to enable compression. -c cipher Selects the cipher to use for encrypting the data transfer. This option is directly passed to ssh(1). -F ssh_config Specifies an alternative per-user configuration file for ssh. This option is directly passed to ssh(1). -i identity_file Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to ssh(1). -l limit Limits the used bandwidth, specified in Kbit/s. -o ssh_option Can be used to pass options to ssh in the format used in ssh_config(5). This is useful for specifying options for which there is no separate scp command-line flag. For full details of the options listed below, and their possible values, see ssh_config(5). AddressFamily BatchMode BindAddress CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher Ciphers Compression CompressionLevel ConnectionAttempts ConnectTimeout ControlMaster ControlPath ControlPersist GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials HashKnownHosts Host HostbasedAuthentication HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName IdentityFile IdentitiesOnly IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand PubkeyAcceptedKeyTypes PubkeyAuthentication RekeyLimit RhostsRSAAuthentication RSAAuthentication SendEnv ServerAliveInterval ServerAliveCountMax StrictHostKeyChecking TCPKeepAlive UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile VerifyHostKeyDNS -P port Specifies the port to connect to on the remote host. Note that this option is written with a capital M-bM-^@M-^XPM-bM-^@M-^Y, because -p is already reserved for preserving the times and modes of the file. -p Preserves modification times, access times, and modes from the original file. -q Quiet mode: disables the progress meter as well as warning and diagnostic messages from ssh(1). -r Recursively copy entire directories. Note that scp follows symbolic links encountered in the tree traversal. -S program Name of program to use for the encrypted connection. The program must understand ssh(1) options. -v Verbose mode. Causes scp and ssh(1) to print debugging messages about their progress. This is helpful in debugging connection, authentication, and configuration problems. EXIT STATUS The scp utility exitsM-BM- 0 on success, andM-BM- >0 if an error occurs. SEE ALSO sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh_config(5), sshd(8) HISTORY scp is based on the rcp program in BSD source code from the Regents of the University of California. AUTHORS Timo Rinne Tatu Ylonen OpenBSD 5.9 September 25, 2015 OpenBSD 5.9 openssh-7.2p2/ssh-add.0010064400017500001750000000124531267007032700130670ustar00djmdjmSSH-ADD(1) General Commands Manual SSH-ADD(1) NAME ssh-add M-bM-^@M-^S adds private key identities to the authentication agent SYNOPSIS ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...] ssh-add -s pkcs11 ssh-add -e pkcs11 DESCRIPTION ssh-add adds private key identities to the authentication agent, ssh-agent(1). When run without arguments, it adds the files ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/identity. After loading a private key, ssh-add will try to load corresponding certificate information from the filename obtained by appending -cert.pub to the name of the private key file. Alternative file names can be given on the command line. If any file requires a passphrase, ssh-add asks for the passphrase from the user. The passphrase is read from the user's tty. ssh-add retries the last passphrase if multiple identity files are given. The authentication agent must be running and the SSH_AUTH_SOCK environment variable must contain the name of its socket for ssh-add to work. The options are as follows: -c Indicates that added identities should be subject to confirmation before being used for authentication. Confirmation is performed by ssh-askpass(1). Successful confirmation is signaled by a zero exit status from ssh-askpass(1), rather than text entered into the requester. -D Deletes all identities from the agent. -d Instead of adding identities, removes identities from the agent. If ssh-add has been run without arguments, the keys for the default identities and their corresponding certificates will be removed. Otherwise, the argument list will be interpreted as a list of paths to public key files to specify keys and certificates to be removed from the agent. If no public key is found at a given path, ssh-add will append .pub and retry. -E fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. -e pkcs11 Remove keys provided by the PKCS#11 shared library pkcs11. -k When loading keys into or deleting keys from the agent, process plain private keys only and skip certificates. -L Lists public key parameters of all identities currently represented by the agent. -l Lists fingerprints of all identities currently represented by the agent. -s pkcs11 Add keys provided by the PKCS#11 shared library pkcs11. -t life Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format specified in sshd_config(5). -X Unlock the agent. -x Lock the agent with a password. ENVIRONMENT DISPLAY and SSH_ASKPASS If ssh-add needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh-add does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS (by default M-bM-^@M-^\ssh-askpassM-bM-^@M-^]) and open an X11 window to read the passphrase. This is particularly useful when calling ssh-add from a .xsession or related script. (Note that on some machines it may be necessary to redirect the input from /dev/null to make this work.) SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to communicate with the agent. FILES ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of the user. ~/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. ~/.ssh/id_ecdsa Contains the protocol version 2 ECDSA authentication identity of the user. ~/.ssh/id_ed25519 Contains the protocol version 2 Ed25519 authentication identity of the user. ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. Identity files should not be readable by anyone but the user. Note that ssh-add ignores identity files if they are accessible by others. EXIT STATUS Exit status is 0 on success, 1 if the specified command fails, and 2 if ssh-add is unable to contact the authentication agent. SEE ALSO ssh(1), ssh-agent(1), ssh-askpass(1), ssh-keygen(1), sshd(8) AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. OpenBSD 5.9 March 30, 2015 OpenBSD 5.9 openssh-7.2p2/ssh-agent.0010064400017500001750000000121661267007032700134360ustar00djmdjmSSH-AGENT(1) General Commands Manual SSH-AGENT(1) NAME ssh-agent M-bM-^@M-^S authentication agent SYNOPSIS ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash] [-t life] [command [arg ...]] ssh-agent [-c | -s] -k DESCRIPTION ssh-agent is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA, Ed25519). ssh-agent is usually started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh(1). The agent initially does not have any private keys. Keys are added using ssh(1) (see AddKeysToAgent in ssh_config(5) for details) or ssh-add(1). Multiple identities may be stored in ssh-agent concurrently and ssh(1) will automatically use them if present. ssh-add(1) is also used to remove keys from ssh-agent and to query the keys that are held in one. The options are as follows: -a bind_address Bind the agent to the UNIX-domain socket bind_address. The default is $TMPDIR/ssh-XXXXXXXXXX/agent.. -c Generate C-shell commands on stdout. This is the default if SHELL looks like it's a csh style of shell. -D Foreground mode. When this option is specified ssh-agent will not fork. -d Debug mode. When this option is specified ssh-agent will not fork and will write debug information to standard error. -E fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. -k Kill the current agent (given by the SSH_AGENT_PID environment variable). -s Generate Bourne shell commands on stdout. This is the default if SHELL does not look like it's a csh style of shell. -t life Set a default value for the maximum lifetime of identities added to the agent. The lifetime may be specified in seconds or in a time format specified in sshd_config(5). A lifetime specified for an identity with ssh-add(1) overrides this value. Without this option the default maximum lifetime is forever. If a command line is given, this is executed as a subprocess of the agent. When the command dies, so does the agent. The idea is that the agent is run in the user's local PC, laptop, or terminal. Authentication data need not be stored on any other machine, and authentication passphrases never go over the network. However, the connection to the agent is forwarded over SSH remote logins, and the user can thus use the privileges given by the identities anywhere in the network in a secure way. There are two main ways to get an agent set up: The first is that the agent starts a new subcommand into which some environment variables are exported, eg ssh-agent xterm &. The second is that the agent prints the needed shell commands (either sh(1) or csh(1) syntax can be generated) which can be evaluated in the calling shell, eg eval `ssh-agent -s` for Bourne-type shells such as sh(1) or ksh(1) and eval `ssh-agent -c` for csh(1) and derivatives. Later ssh(1) looks at these variables and uses them to establish a connection to the agent. The agent will never send a private key over its request channel. Instead, operations that require a private key will be performed by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent. A UNIX-domain socket is created and the name of this socket is stored in the SSH_AUTH_SOCK environment variable. The socket is made accessible only to the current user. This method is easily abused by root or another instance of the same user. The SSH_AGENT_PID environment variable holds the agent's process ID. The agent exits automatically when the command given on the command line terminates. FILES $TMPDIR/ssh-XXXXXXXXXX/agent. UNIX-domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. SEE ALSO ssh(1), ssh-add(1), ssh-keygen(1), sshd(8) AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. OpenBSD 5.9 November 15, 2015 OpenBSD 5.9 openssh-7.2p2/ssh-keygen.0010064400017500001750000000663571267007033000136270ustar00djmdjmSSH-KEYGEN(1) General Commands Manual SSH-KEYGEN(1) NAME ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion SYNOPSIS ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] [-N new_passphrase] [-C comment] [-f output_keyfile] ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] ssh-keygen -i [-m key_format] [-f input_keyfile] ssh-keygen -e [-m key_format] [-f input_keyfile] ssh-keygen -y [-f input_keyfile] ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile] ssh-keygen -B [-f input_keyfile] ssh-keygen -D pkcs11 ssh-keygen -F hostname [-f known_hosts_file] [-l] ssh-keygen -H [-f known_hosts_file] ssh-keygen -R hostname [-f known_hosts_file] ssh-keygen -r hostname [-f input_keyfile] [-g] ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] [-j start_line] [-K checkpt] [-W generator] ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals] [-O option] [-V validity_interval] [-z serial_number] file ... ssh-keygen -L [-f input_keyfile] ssh-keygen -A ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] file ... ssh-keygen -Q -f krl_file file ... DESCRIPTION ssh-keygen generates, manages and converts authentication keys for ssh(1). ssh-keygen can create keys for use by SSH protocol versions 1 and 2. Protocol 1 should not be used and is only offered to support legacy devices. It suffers from a number of cryptographic weaknesses and doesn't support many of the advanced features available for protocol 2. The type of key to be generated is specified with the -t option. If invoked without any arguments, ssh-keygen will generate an RSA key for use in SSH protocol 2 connections. ssh-keygen is also used to generate groups for use in Diffie-Hellman group exchange (DH-GEX). See the MODULI GENERATION section for details. Finally, ssh-keygen can be used to generate and update Key Revocation Lists, and to test whether given keys have been revoked by one. See the KEY REVOCATION LISTS section for details. Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in ~/.ssh/identity, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa. Additionally, the system administrator may use this to generate host keys, as seen in /etc/rc. Normally this program generates the key and asks for a file in which to store the private key. The public key is stored in a file with the same name but M-bM-^@M-^\.pubM-bM-^@M-^] appended. The program also asks for a passphrase. The passphrase may be empty to indicate no passphrase (host keys must have an empty passphrase), or it may be a string of arbitrary length. A passphrase is similar to a password, except it can be a phrase with a series of words, punctuation, numbers, whitespace, or any string of characters you want. Good passphrases are 10-30 characters long, are not simple sentences or otherwise easily guessable (English prose has only 1-2 bits of entropy per character, and provides very bad passphrases), and contain a mix of upper and lowercase letters, numbers, and non- alphanumeric characters. The passphrase can be changed later by using the -p option. There is no way to recover a lost passphrase. If the passphrase is lost or forgotten, a new key must be generated and the corresponding public key copied to other machines. For RSA1 keys, there is also a comment field in the key file that is only for convenience to the user to help identify the key. The comment can tell what the key is for, or whatever is useful. The comment is initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the key is created, but can be changed using the -c option. After a key is generated, instructions below detail where the keys should be placed to be activated. The options are as follows: -A For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for which host keys do not exist, generate the host keys with the default key file path, an empty passphrase, default bits for the key type, and default comment. This is used by /etc/rc to generate new host keys. -a rounds When saving a new-format private key (i.e. an ed25519 key or any SSH protocol 2 key when the -o flag is set), this option specifies the number of KDF (key derivation function) rounds used. Higher numbers result in slower passphrase verification and increased resistance to brute-force password cracking (should the keys be stolen). When screening DH-GEX candidates ( using the -T command). This option specifies the number of primality tests to perform. -B Show the bubblebabble digest of specified private or public key file. -b bits Specifies the number of bits in the key to create. For RSA keys, the minimum size is 1024 bits and the default is 2048 bits. Generally, 2048 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, the -b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. Ed25519 keys have a fixed length and the -b flag will be ignored. -C comment Provides a new comment. -c Requests changing the comment in the private and public key files. This operation is only supported for RSA1 keys. The program will prompt for the file containing the private keys, for the passphrase if the key has one, and for the new comment. -D pkcs11 Download the RSA public keys provided by the PKCS#11 shared library pkcs11. When used in combination with -s, this option indicates that a CA key resides in a PKCS#11 token (see the CERTIFICATES section for details). -E fingerprint_hash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. -e This option will read a private or public OpenSSH key file and print to stdout the key in one of the formats specified by the -m option. The default export format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. This option allows exporting OpenSSH keys for use by other programs, including several commercial SSH implementations. -F hostname Search for the specified hostname in a known_hosts file, listing any occurrences found. This option is useful to find hashed host names or addresses and may also be used in conjunction with the -H option to print found keys in a hashed format. -f filename Specifies the filename of the key file. -G output_file Generate candidate primes for DH-GEX. These primes must be screened for safety (using the -T option) before use. -g Use generic DNS format when printing fingerprint resource records using the -r command. -H Hash a known_hosts file. This replaces all hostnames and addresses with hashed representations within the specified file; the original content is moved to a file with a .old suffix. These hashes may be used normally by ssh and sshd, but they do not reveal identifying information should the file's contents be disclosed. This option will not modify existing hashed hostnames and is therefore safe to use on files that mix hashed and non- hashed names. -h When signing a key, create a host certificate instead of a user certificate. Please see the CERTIFICATES section for details. -I certificate_identity Specify the key identity when signing a public key. Please see the CERTIFICATES section for details. -i This option will read an unencrypted private (or public) key file in the format specified by the -m option and print an OpenSSH compatible private (or public) key to stdout. This option allows importing keys from other software, including several commercial SSH implementations. The default import format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. -J num_lines Exit after screening the specified number of lines while performing DH candidate screening using the -T option. -j start_line Start screening at the specified line number while performing DH candidate screening using the -T option. -K checkpt Write the last line processed to the file checkpt while performing DH candidate screening using the -T option. This will be used to skip lines in the input file that have already been processed if the job is restarted. -k Generate a KRL file. In this mode, ssh-keygen will generate a KRL file at the location specified via the -f flag that revokes every key or certificate presented on the command line. Keys/certificates to be revoked may be specified by public key file or using the format described in the KEY REVOCATION LISTS section. -L Prints the contents of one or more certificates. -l Show fingerprint of specified public key file. Private RSA1 keys are also supported. For RSA and DSA keys ssh-keygen tries to find the matching public key file and prints its fingerprint. If combined with -v, an ASCII art representation of the key is supplied with the fingerprint. -M memory Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX. -m key_format Specify a key format for the -i (import) or -e (export) conversion options. The supported key formats are: M-bM-^@M-^\RFC4716M-bM-^@M-^] (RFC 4716/SSH2 public or private key), M-bM-^@M-^\PKCS8M-bM-^@M-^] (PEM PKCS8 public key) or M-bM-^@M-^\PEMM-bM-^@M-^] (PEM public key). The default conversion format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. -N new_passphrase Provides the new passphrase. -n principals Specify one or more principals (user or host names) to be included in a certificate when signing a key. Multiple principals may be specified, separated by commas. Please see the CERTIFICATES section for details. -O option Specify a certificate option when signing a key. This option may be specified multiple times. Please see the CERTIFICATES section for details. The options that are valid for user certificates are: clear Clear all enabled permissions. This is useful for clearing the default set of permissions so permissions may be added individually. force-command=command Forces the execution of command instead of any shell or command specified by the user when the certificate is used for authentication. no-agent-forwarding Disable ssh-agent(1) forwarding (permitted by default). no-port-forwarding Disable port forwarding (permitted by default). no-pty Disable PTY allocation (permitted by default). no-user-rc Disable execution of ~/.ssh/rc by sshd(8) (permitted by default). no-x11-forwarding Disable X11 forwarding (permitted by default). permit-agent-forwarding Allows ssh-agent(1) forwarding. permit-port-forwarding Allows port forwarding. permit-pty Allows PTY allocation. permit-user-rc Allows execution of ~/.ssh/rc by sshd(8). permit-x11-forwarding Allows X11 forwarding. source-address=address_list Restrict the source addresses from which the certificate is considered valid. The address_list is a comma- separated list of one or more address/netmask pairs in CIDR format. At present, no options are valid for host keys. -o Causes ssh-keygen to save private keys using the new OpenSSH format rather than the more compatible PEM format. The new format has increased resistance to brute-force password cracking but is not supported by versions of OpenSSH prior to 6.5. Ed25519 keys always use the new private key format. -P passphrase Provides the (old) passphrase. -p Requests changing the passphrase of a private key file instead of creating a new private key. The program will prompt for the file containing the private key, for the old passphrase, and twice for the new passphrase. -Q Test whether keys have been revoked in a KRL. -q Silence ssh-keygen. -R hostname Removes all keys belonging to hostname from a known_hosts file. This option is useful to delete hashed hosts (see the -H option above). -r hostname Print the SSHFP fingerprint resource record named hostname for the specified public key file. -S start Specify start point (in hex) when generating candidate moduli for DH-GEX. -s ca_key Certify (sign) a public key using the specified CA key. Please see the CERTIFICATES section for details. When generating a KRL, -s specifies a path to a CA public key file used to revoke certificates directly by key ID or serial number. See the KEY REVOCATION LISTS section for details. -T output_file Test DH group exchange candidate primes (generated using the -G option) for safety. -t dsa | ecdsa | ed25519 | rsa | rsa1 Specifies the type of key to create. The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. -u Update a KRL. When specified with -k, keys listed via the command line are added to the existing KRL rather than a new KRL being created. -V validity_interval Specify a validity interval when signing a certificate. A validity interval may consist of a single time, indicating that the certificate is valid beginning now and expiring at that time, or may consist of two times separated by a colon to indicate an explicit time interval. The start time may be specified as a date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting of a minus sign followed by a relative time in the format described in the TIME FORMATS section of sshd_config(5). The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time starting with a plus character. For example: M-bM-^@M-^\+52w1dM-bM-^@M-^] (valid from now to 52 weeks and one day from now), M-bM-^@M-^\-4w:+4wM-bM-^@M-^] (valid from four weeks ago to four weeks from now), M-bM-^@M-^\20100101123000:20110101123000M-bM-^@M-^] (valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011), M-bM-^@M-^\-1d:20110101M-bM-^@M-^] (valid from yesterday to midnight, January 1st, 2011). -v Verbose mode. Causes ssh-keygen to print debugging messages about its progress. This is helpful for debugging moduli generation. Multiple -v options increase the verbosity. The maximum is 3. -W generator Specify desired generator when testing candidate moduli for DH- GEX. -y This option will read a private OpenSSH format file and print an OpenSSH public key to stdout. -z serial_number Specifies a serial number to be embedded in the certificate to distinguish this certificate from others from the same CA. The default serial number is zero. When generating a KRL, the -z flag is used to specify a KRL version number. MODULI GENERATION ssh-keygen may be used to generate groups for the Diffie-Hellman Group Exchange (DH-GEX) protocol. Generating these groups is a two-step process: first, candidate primes are generated using a fast, but memory intensive process. These candidate primes are then tested for suitability (a CPU-intensive process). Generation of primes is performed using the -G option. The desired length of the primes may be specified by the -b option. For example: # ssh-keygen -G moduli-2048.candidates -b 2048 By default, the search for primes begins at a random point in the desired length range. This may be overridden using the -S option, which specifies a different start point (in hex). Once a set of candidates have been generated, they must be screened for suitability. This may be performed using the -T option. In this mode ssh-keygen will read candidates from standard input (or a file specified using the -f option). For example: # ssh-keygen -T moduli-2048 -f moduli-2048.candidates By default, each candidate will be subjected to 100 primality tests. This may be overridden using the -a option. The DH generator value will be chosen automatically for the prime under consideration. If a specific generator is desired, it may be requested using the -W option. Valid generator values are 2, 3, and 5. Screened DH groups may be installed in /etc/moduli. It is important that this file contains moduli of a range of bit lengths and that both ends of a connection share common moduli. CERTIFICATES ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). ssh-keygen supports two types of certificates: user and host. User certificates authenticate users to servers, whereas host certificates authenticate server hosts to users. To generate a user certificate: $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub The resultant certificate will be placed in /path/to/user_key-cert.pub. A host certificate requires the -h option: $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub The host certificate will be output to /path/to/host_key-cert.pub. It is possible to sign using a CA key stored in a PKCS#11 token by providing the token library using -D and identifying the CA key by providing its public half as an argument to -s: $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub In all cases, key_id is a "key identifier" that is logged by the server when the certificate is used for authentication. Certificates may be limited to be valid for a set of principal (user/host) names. By default, generated certificates are valid for all users or hosts. To generate a certificate for a specified set of principals: $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub Additional limitations on the validity and use of user certificates may be specified through certificate options. A certificate option may disable features of the SSH session, may be valid only when presented from particular source addresses or may force the use of a specific command. For a list of valid certificate options, see the documentation for the -O option above. Finally, certificates may be defined with a validity lifetime. The -V option allows specification of certificate start and end times. A certificate that is presented at a time outside this range will not be considered valid. By default, certificates are valid from UNIX Epoch to the distant future. For certificates to be used for user or host authentication, the CA public key must be trusted by sshd(8) or ssh(1). Please refer to those manual pages for details. KEY REVOCATION LISTS ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs). These binary files specify keys or certificates to be revoked using a compact format, taking as little as one bit per certificate if they are being revoked by serial number. KRLs may be generated using the -k flag. This option reads one or more files from the command line and generates a new KRL. The files may either contain a KRL specification (see below) or public keys, listed one per line. Plain public keys are revoked by listing their hash or contents in the KRL and certificates revoked by serial number or key ID (if the serial is zero or not available). Revoking keys using a KRL specification offers explicit control over the types of record used to revoke keys and may be used to directly revoke certificates by serial number or key ID without having the complete original certificate on hand. A KRL specification consists of lines containing one of the following directives followed by a colon and some directive-specific information. serial: serial_number[-serial_number] Revokes a certificate with the specified serial number. Serial numbers are 64-bit values, not including zero and may be expressed in decimal, hex or octal. If two serial numbers are specified separated by a hyphen, then the range of serial numbers including and between each is revoked. The CA key must have been specified on the ssh-keygen command line using the -s option. id: key_id Revokes a certificate with the specified key ID string. The CA key must have been specified on the ssh-keygen command line using the -s option. key: public_key Revokes the specified key. If a certificate is listed, then it is revoked as a plain public key. sha1: public_key Revokes the specified key by its SHA1 hash. KRLs may be updated using the -u flag in addition to -k. When this option is specified, keys listed via the command line are merged into the KRL, adding to those already there. It is also possible, given a KRL, to test whether it revokes a particular key (or keys). The -Q flag will query an existing KRL, testing each key specified on the command line. If any key listed on the command line has been revoked (or an error encountered) then ssh-keygen will exit with a non-zero exit status. A zero exit status will only be returned if no key was revoked. FILES ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt the private part of this file using 3DES. This file is not automatically accessed by ssh-keygen but it is offered as the default file for the private key. ssh(1) will read this file when a login attempt is made. ~/.ssh/identity.pub Contains the protocol version 1 RSA public key for authentication. The contents of this file should be added to ~/.ssh/authorized_keys on all machines where the user wishes to log in using RSA authentication. There is no need to keep the contents of this file secret. ~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 ~/.ssh/id_rsa Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt the private part of this file using 128-bit AES. This file is not automatically accessed by ssh-keygen but it is offered as the default file for the private key. ssh(1) will read this file when a login attempt is made. ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public key for authentication. The contents of this file should be added to ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. /etc/moduli Contains Diffie-Hellman groups used for DH-GEX. The file format is described in moduli(5). SEE ALSO ssh(1), ssh-add(1), ssh-agent(1), moduli(5), sshd(8) The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006. AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 openssh-7.2p2/ssh-keyscan.0010064400017500001750000000111121267007033000137550ustar00djmdjmSSH-KEYSCAN(1) General Commands Manual SSH-KEYSCAN(1) NAME ssh-keyscan M-bM-^@M-^S gather ssh public keys SYNOPSIS ssh-keyscan [-46cHv] [-f file] [-p port] [-T timeout] [-t type] [host | addrlist namelist] ... DESCRIPTION ssh-keyscan is a utility for gathering the public ssh host keys of a number of hosts. It was designed to aid in building and verifying ssh_known_hosts files. ssh-keyscan provides a minimal interface suitable for use by shell and perl scripts. ssh-keyscan uses non-blocking socket I/O to contact as many hosts as possible in parallel, so it is very efficient. The keys from a domain of 1,000 hosts can be collected in tens of seconds, even when some of those hosts are down or do not run ssh. For scanning, one does not need login access to the machines that are being scanned, nor does the scanning process involve any encryption. The options are as follows: -4 Forces ssh-keyscan to use IPv4 addresses only. -6 Forces ssh-keyscan to use IPv6 addresses only. -c Request certificates from target hosts instead of plain keys. -f file Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line. If - is supplied instead of a filename, ssh-keyscan will read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from the standard input. -H Hash all hostnames and addresses in the output. Hashed names may be used normally by ssh and sshd, but they do not reveal identifying information should the file's contents be disclosed. -p port Port to connect to on the remote host. -T timeout Set the timeout for connection attempts. If timeout seconds have elapsed since a connection was initiated to a host or since the last time anything was read from that host, then the connection is closed and the host in question considered unavailable. Default is 5 seconds. -t type Specifies the type of the key to fetch from the scanned hosts. The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. Multiple values may be specified by separating them with commas. The default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys. -v Verbose mode. Causes ssh-keyscan to print debugging messages about its progress. SECURITY If an ssh_known_hosts file is constructed using ssh-keyscan without verifying the keys, users will be vulnerable to man in the middle attacks. On the other hand, if the security model allows such a risk, ssh-keyscan can help in the detection of tampered keyfiles or man in the middle attacks which have begun after the ssh_known_hosts file was created. FILES Input format: 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 Output format for RSA1 keys: host-or-namelist bits exponent modulus Output format for RSA, DSA, ECDSA, and Ed25519 keys: host-or-namelist keytype base64-encoded-key Where keytype is either M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or M-bM-^@M-^\ssh-rsaM-bM-^@M-^]. /etc/ssh/ssh_known_hosts EXAMPLES Print the rsa host key for machine hostname: $ ssh-keyscan hostname Find all hosts from the file ssh_hosts which have new or different keys from those in the sorted file ssh_known_hosts: $ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \ sort -u - ssh_known_hosts | diff ssh_known_hosts - SEE ALSO ssh(1), sshd(8) AUTHORS David Mazieres wrote the initial version, and Wayne Davison added support for protocol version 2. BUGS It generates "Connection closed by remote host" messages on the consoles of all the machines it scans if the server is older than version 2.9. This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. OpenBSD 5.9 November 8, 2015 OpenBSD 5.9 openssh-7.2p2/ssh.0010064400017500001750000001360641267007033000123400ustar00djmdjmSSH(1) General Commands Manual SSH(1) NAME ssh M-bM-^@M-^S OpenSSH SSH client (remote login program) SYNOPSIS ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command] DESCRIPTION ssh (SSH client) is a program for logging into a remote machine and for executing commands on a remote machine. It is intended to provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections, arbitrary TCP ports and UNIX-domain sockets can also be forwarded over the secure channel. ssh connects and logs into the specified hostname (with optional user name). The user must prove his/her identity to the remote machine using one of several methods (see below). If command is specified, it is executed on the remote host instead of a login shell. The options are as follows: -1 Forces ssh to try protocol version 1 only. -2 Forces ssh to try protocol version 2 only. -4 Forces ssh to use IPv4 addresses only. -6 Forces ssh to use IPv6 addresses only. -A Enables forwarding of the authentication agent connection. This can also be specified on a per-host basis in a configuration file. Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's UNIX-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. -a Disables forwarding of the authentication agent connection. -b bind_address Use bind_address on the local machine as the source address of the connection. Only useful on systems with more than one address. -C Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11, TCP and UNIX-domain connections). The compression algorithm is the same used by gzip(1), and the M-bM-^@M-^\levelM-bM-^@M-^] can be controlled by the CompressionLevel option for protocol version 1. Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks. The default value can be set on a host-by-host basis in the configuration files; see the Compression option. -c cipher_spec Selects the cipher specification for encrypting the session. Protocol version 1 allows specification of a single cipher. The supported values are M-bM-^@M-^\3desM-bM-^@M-^], M-bM-^@M-^\blowfishM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^]. For protocol version 2, cipher_spec is a comma-separated list of ciphers listed in order of preference. See the Ciphers keyword in ssh_config(5) for more information. -D [bind_address:]port Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. IPv6 addresses can be specified by enclosing the address in square brackets. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. -E log_file Append debug logs to log_file instead of standard error. -e escape_char Sets the escape character for sessions with a pty (default: M-bM-^@M-^X~M-bM-^@M-^Y). The escape character is only recognized at the beginning of a line. The escape character followed by a dot (M-bM-^@M-^X.M-bM-^@M-^Y) closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once. Setting the character to M-bM-^@M-^\noneM-bM-^@M-^] disables any escapes and makes the session fully transparent. -F configfile Specifies an alternative per-user configuration file. If a configuration file is given on the command line, the system-wide configuration file (/etc/ssh/ssh_config) will be ignored. The default for the per-user configuration file is ~/.ssh/config. -f Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. This implies -n. The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm. If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^], then a client started with -f will wait for all remote port forwards to be successfully established before placing itself in the background. -G Causes ssh to print its configuration after evaluating Host and Match blocks and exit. -g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified on the master process. -I pkcs11 Specify the PKCS#11 shared library ssh should use to communicate with a PKCS#11 token providing the user's private RSA key. -i identity_file Selects a file from which the identity (private key) for public key authentication is read. The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple -i options (and multiple identities specified in configuration files). If no certificates have been explicitly specified by the CertificateFile directive, ssh will also try to load certificate information from the filename obtained by appending -cert.pub to identity filenames. -K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. -k Disables forwarding (delegation) of GSSAPI credentials to the server. -L [bind_address:]port:host:hostport -L [bind_address:]port:remote_socket -L local_socket:host:hostport -L local_socket:remote_socket Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side. This works by allocating a socket to listen to either a TCP port on the local side, optionally bound to the specified bind_address, or to a Unix socket. Whenever a connection is made to the local port or socket, the connection is forwarded over the secure channel, and a connection is made to either host port hostport, or the Unix socket remote_socket, from the remote machine. Port forwardings can also be specified in the configuration file. Only the superuser can forward privileged ports. IPv6 addresses can be specified by enclosing the address in square brackets. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. -l login_name Specifies the user to log in as on the remote machine. This also may be specified on a per-host basis in the configuration file. -M Places the ssh client into M-bM-^@M-^\masterM-bM-^@M-^] mode for connection sharing. Multiple -M options places ssh into M-bM-^@M-^\masterM-bM-^@M-^] mode with confirmation required before slave connections are accepted. Refer to the description of ControlMaster in ssh_config(5) for details. -m mac_spec A comma-separated list of MAC (message authentication code) algorithms, specified in order of preference. See the MACs keyword for more information. -N Do not execute a remote command. This is useful for just forwarding ports. -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A common trick is to use this to run X11 programs on a remote machine. For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel. The ssh program will be put in the background. (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.) -O ctl_cmd Control an active connection multiplexing master process. When the -O option is specified, the ctl_cmd argument is interpreted and passed to the master process. Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^] (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel forwardings), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] (request the master to stop accepting further multiplexing requests). -o option Can be used to give options in the format used in the configuration file. This is useful for specifying options for which there is no separate command-line flag. For full details of the options listed below, and their possible values, see ssh_config(5). AddKeysToAgent AddressFamily BatchMode BindAddress CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher Ciphers ClearAllForwardings Compression CompressionLevel ConnectionAttempts ConnectTimeout ControlMaster ControlPath ControlPersist DynamicForward EscapeChar ExitOnForwardFailure FingerprintHash ForwardAgent ForwardX11 ForwardX11Timeout ForwardX11Trusted GatewayPorts GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials HashKnownHosts Host HostbasedAuthentication HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName IdentityFile IdentitiesOnly IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LocalCommand LocalForward LogLevel MACs Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PermitLocalCommand PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand ProxyUseFdpass PubkeyAcceptedKeyTypes PubkeyAuthentication RekeyLimit RemoteForward RequestTTY RhostsRSAAuthentication RSAAuthentication SendEnv ServerAliveInterval ServerAliveCountMax StreamLocalBindMask StreamLocalBindUnlink StrictHostKeyChecking TCPKeepAlive Tunnel TunnelDevice UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile VerifyHostKeyDNS VisualHostKey XAuthLocation -p port Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. -Q query_option Queries ssh for the algorithms supported for the specified version 2. The available features are: cipher (supported symmetric ciphers), cipher-auth (supported symmetric ciphers that support authenticated encryption), mac (supported message integrity codes), kex (key exchange algorithms), key (key types), key-cert (certificate key types), key-plain (non-certificate key types), and protocol-version (supported SSH protocol versions). -q Quiet mode. Causes most warning and diagnostic messages to be suppressed. -R [bind_address:]port:host:hostport -R [bind_address:]port:local_socket -R remote_socket:host:hostport -R remote_socket:local_socket Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the given host and port, or Unix socket, on the local side. This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side. Whenever a connection is made to this port or Unix socket, the connection is forwarded over the secure channel, and a connection is made to either host port hostport, or local_socket, from the local machine. Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square brackets. By default, TCP listening sockets on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address M-bM-^@M-^X*M-bM-^@M-^Y, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)). If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically allocated on the server and reported to the client at run time. When used together with -O forward the allocated port will be printed to the standard output. -S ctl_path Specifies the location of a control socket for connection sharing, or the string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. Refer to the description of ControlPath and ControlMaster in ssh_config(5) for details. -s May be used to request invocation of a subsystem on the remote system. Subsystems facilitate the use of SSH as a secure transport for other applications (e.g. sftp(1)). The subsystem is specified as the remote command. -T Disable pseudo-terminal allocation. -t Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty. -V Display the version number and exit. -v Verbose mode. Causes ssh to print debugging messages about its progress. This is helpful in debugging connection, authentication, and configuration problems. Multiple -v options increase the verbosity. The maximum is 3. -W host:port Requests that standard input and output on the client be forwarded to host on port over the secure channel. Implies -N, -T, ExitOnForwardFailure and ClearAllForwardings. -w local_tun[:remote_tun] Requests tunnel device forwarding with the specified tun(4) devices between the client (local_tun) and the server (remote_tun). The devices may be specified by numerical ID or the keyword M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device. If remote_tun is not specified, it defaults to M-bM-^@M-^\anyM-bM-^@M-^]. See also the Tunnel and TunnelDevice directives in ssh_config(5). If the Tunnel directive is unset, it is set to the default tunnel mode, which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. -X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. X11 forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the user's X authorization database) can access the local X11 display through the forwarded connection. An attacker may then be able to perform activities such as keystroke monitoring. For this reason, X11 forwarding is subjected to X11 SECURITY extension restrictions by default. Please refer to the ssh -Y option and the ForwardX11Trusted directive in ssh_config(5) for more information. -x Disables X11 forwarding. -Y Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. -y Send log information using the syslog(3) system module. By default this information is sent to stderr. ssh may additionally obtain configuration data from a per-user configuration file and a system-wide configuration file. The file format and configuration options are described in ssh_config(5). AUTHENTICATION The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the Protocol option in ssh_config(5) or the -1 and -2 options (see above). Protocol 1 should not be used and is only offered to support legacy devices. It suffers from a number of cryptographic weaknesses and doesn't support many of the advanced features available for protocol 2. The methods available for authentication are: GSSAPI-based authentication, host-based authentication, public key authentication, challenge-response authentication, and password authentication. Authentication methods are tried in the order specified above, though PreferredAuthentications can be used to change the default order. Host-based authentication works as follows: If the machine the user logs in from is listed in /etc/hosts.equiv or /etc/shosts.equiv on the remote machine, and the user names are the same on both sides, or if the files ~/.rhosts or ~/.shosts exist in the user's home directory on the remote machine and contain a line containing the name of the client machine and the name of the user on that machine, the user is considered for login. Additionally, the server must be able to verify the client's host key (see the description of /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts, below) for login to be permitted. This authentication method closes security holes due to IP spoofing, DNS spoofing, and routing spoofing. [Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the rlogin/rsh protocol in general, are inherently insecure and should be disabled if security is desired.] Public key authentication works as follows: The scheme is based on public-key cryptography, using cryptosystems where encryption and decryption are done using separate keys, and it is unfeasible to derive the decryption key from the encryption key. The idea is that each user creates a public/private key pair for authentication purposes. The server knows the public key, and only the user knows the private key. ssh implements public key authentication protocol automatically, using one of the DSA, ECDSA, Ed25519 or RSA algorithms. The HISTORY section of ssl(8) contains a brief discussion of the DSA and RSA algorithms. The file ~/.ssh/authorized_keys lists the public keys that are permitted for logging in. When the user logs in, the ssh program tells the server which key pair it would like to use for authentication. The client proves that it has access to the private key and the server checks that the corresponding public key is authorized to accept the account. The user creates his/her key pair by running ssh-keygen(1). This stores the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (DSA), ~/.ssh/id_ecdsa (ECDSA), ~/.ssh/id_ed25519 (Ed25519), or ~/.ssh/id_rsa (RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (DSA), ~/.ssh/id_ecdsa.pub (ECDSA), ~/.ssh/id_ed25519.pub (Ed25519), or ~/.ssh/id_rsa.pub (RSA) in the user's home directory. The user should then copy the public key to ~/.ssh/authorized_keys in his/her home directory on the remote machine. The authorized_keys file corresponds to the conventional ~/.rhosts file, and has one key per line, though the lines can be very long. After this, the user can log in without giving the password. A variation on public key authentication is available in the form of certificate authentication: instead of a set of public/private keys, signed certificates are used. This has the advantage that a single trusted certification authority can be used in place of many public/private keys. See the CERTIFICATES section of ssh-keygen(1) for more information. The most convenient way to use public key or certificate authentication may be with an authentication agent. See ssh-agent(1) and (optionally) the AddKeysToAgent directive in ssh_config(5) for more information. Challenge-response authentication works as follows: The server sends an arbitrary "challenge" text, and prompts for a response. Examples of challenge-response authentication include BSD Authentication (see login.conf(5)) and PAM (some non-OpenBSD systems). Finally, if other authentication methods fail, ssh prompts the user for a password. The password is sent to the remote host for checking; however, since all communications are encrypted, the password cannot be seen by someone listening on the network. ssh automatically maintains and checks a database containing identification for all hosts it has ever been used with. Host keys are stored in ~/.ssh/known_hosts in the user's home directory. Additionally, the file /etc/ssh/ssh_known_hosts is automatically checked for known hosts. Any new hosts are automatically added to the user's file. If a host's identification ever changes, ssh warns about this and disables password authentication to prevent server spoofing or man-in-the-middle attacks, which could otherwise be used to circumvent the encryption. The StrictHostKeyChecking option can be used to control logins to machines whose host key is not known or has changed. When the user's identity has been accepted by the server, the server either executes the given command in a non-interactive session or, if no command has been specified, logs into the machine and gives the user a normal shell as an interactive session. All communication with the remote command or shell will be automatically encrypted. If an interactive session is requested ssh by default will only request a pseudo-terminal (pty) for interactive sessions when the client has one. The flags -T and -t can be used to override this behaviour. If a pseudo-terminal has been allocated the user may use the escape characters noted below. If no pseudo-terminal has been allocated, the session is transparent and can be used to reliably transfer binary data. On most systems, setting the escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent even if a tty is used. The session terminates when the command or shell on the remote machine exits and all X11 and TCP connections have been closed. ESCAPE CHARACTERS When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character. A single tilde character can be sent as ~~ or by following the tilde by a character other than those described below. The escape character must always follow a newline to be interpreted as special. The escape character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option. The supported escapes (assuming the default M-bM-^@M-^X~M-bM-^@M-^Y) are: ~. Disconnect. ~^Z Background ssh. ~# List forwarded connections. ~& Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate. ~? Display a list of escape characters. ~B Send a BREAK to the remote system (only useful if the peer supports it). ~C Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options (see above). It also allows the cancellation of existing port-forwardings with -KL[bind_address:]port for local, -KR[bind_address:]port for remote and -KD[bind_address:]port for dynamic port-forwardings. !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option. ~R Request rekeying of the connection (only useful if the peer supports it). ~V Decrease the verbosity (LogLevel) when errors are being written to stderr. ~v Increase the verbosity (LogLevel) when errors are being written to stderr. TCP FORWARDING Forwarding of arbitrary TCP connections over the secure channel can be specified either on the command line or in a configuration file. One possible application of TCP forwarding is a secure connection to a mail server; another is going through firewalls. In the example below, we look at encrypting communication between an IRC client and server, even though the IRC server does not directly support encrypted communications. This works as follows: the user connects to the remote host using ssh, specifying a port to be used to forward connections to the remote server. After that it is possible to start the service which is to be encrypted on the client machine, connecting to the same local port, and ssh will encrypt and forward the connection. The following example tunnels an IRC session from client machine M-bM-^@M-^\127.0.0.1M-bM-^@M-^] (localhost) to remote server M-bM-^@M-^\server.example.comM-bM-^@M-^]: $ ssh -f -L 1234:localhost:6667 server.example.com sleep 10 $ irc -c '#users' -p 1234 pinky 127.0.0.1 This tunnels a connection to IRC server M-bM-^@M-^\server.example.comM-bM-^@M-^], joining channel M-bM-^@M-^\#usersM-bM-^@M-^], nickname M-bM-^@M-^\pinkyM-bM-^@M-^], using port 1234. It doesn't matter which port is used, as long as it's greater than 1023 (remember, only root can open sockets on privileged ports) and doesn't conflict with any ports already in use. The connection is forwarded to port 6667 on the remote server, since that's the standard port for IRC services. The -f option backgrounds ssh and the remote command M-bM-^@M-^\sleep 10M-bM-^@M-^] is specified to allow an amount of time (10 seconds, in the example) to start the service which is to be tunnelled. If no connections are made within the time specified, ssh will exit. X11 FORWARDING If the ForwardX11 variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the -X, -x, and -Y options above) and the user is using X11 (the DISPLAY environment variable is set), the connection to the X11 display is automatically forwarded to the remote side in such a way that any X11 programs started from the shell (or command) will go through the encrypted channel, and the connection to the real X server will be made from the local machine. The user should not manually set DISPLAY. Forwarding of X11 connections can be configured on the command line or in configuration files. The DISPLAY value set by ssh will point to the server machine, but with a display number greater than zero. This is normal, and happens because ssh creates a M-bM-^@M-^\proxyM-bM-^@M-^] X server on the server machine for forwarding the connections over the encrypted channel. ssh will also automatically set up Xauthority data on the server machine. For this purpose, it will generate a random authorization cookie, store it in Xauthority on the server, and verify that any forwarded connections carry this cookie and replace it by the real cookie when the connection is opened. The real authentication cookie is never sent to the server machine (and no cookies are sent in the plain). If the ForwardAgent variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the -A and -a options above) and the user is using an authentication agent, the connection to the agent is automatically forwarded to the remote side. VERIFYING HOST KEYS When connecting to a server for the first time, a fingerprint of the server's public key is presented to the user (unless the option StrictHostKeyChecking has been disabled). Fingerprints can be determined using ssh-keygen(1): $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key If the fingerprint is already known, it can be matched and the key can be accepted or rejected. If only legacy (MD5) fingerprints for the server are available, the ssh-keygen(1) -E option may be used to downgrade the fingerprint algorithm to match. Because of the difficulty of comparing host keys just by looking at fingerprint strings, there is also support to compare host keys visually, using random art. By setting the VisualHostKey option to M-bM-^@M-^\yesM-bM-^@M-^], a small ASCII graphic gets displayed on every login to a server, no matter if the session itself is interactive or not. By learning the pattern a known server produces, a user can easily find out that the host key has changed when a completely different pattern is displayed. Because these patterns are not unambiguous however, a pattern that looks similar to the pattern remembered only gives a good probability that the host key is the same, not guaranteed proof. To get a listing of the fingerprints along with their random art for all known hosts, the following command line can be used: $ ssh-keygen -lv -f ~/.ssh/known_hosts If the fingerprint is unknown, an alternative method of verification is available: SSH fingerprints verified by DNS. An additional resource record (RR), SSHFP, is added to a zonefile and the connecting client is able to match the fingerprint with that of the key presented. In this example, we are connecting a client to a server, M-bM-^@M-^\host.example.comM-bM-^@M-^]. The SSHFP resource records should first be added to the zonefile for host.example.com: $ ssh-keygen -r host.example.com. The output lines will have to be added to the zonefile. To check that the zone is answering fingerprint queries: $ dig -t SSHFP host.example.com Finally the client connects: $ ssh -o "VerifyHostKeyDNS ask" host.example.com [...] Matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)? See the VerifyHostKeyDNS option in ssh_config(5) for more information. SSH-BASED VIRTUAL PRIVATE NETWORKS ssh contains support for Virtual Private Network (VPN) tunnelling using the tun(4) network pseudo-device, allowing two networks to be joined securely. The sshd_config(5) configuration option PermitTunnel controls whether the server supports this, and at what level (layer 2 or 3 traffic). The following example would connect client network 10.0.50.0/24 with remote network 10.0.99.0/24 using a point-to-point connection from 10.1.1.1 to 10.1.1.2, provided that the SSH server running on the gateway to the remote network, at 192.168.1.15, allows it. On the client: # ssh -f -w 0:1 192.168.1.15 true # ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252 # route add 10.0.99.0/24 10.1.1.2 On the server: # ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252 # route add 10.0.50.0/24 10.1.1.1 Client access may be more finely tuned via the /root/.ssh/authorized_keys file (see below) and the PermitRootLogin server option. The following entry would permit connections on tun(4) device 1 from user M-bM-^@M-^\janeM-bM-^@M-^] and on tun device 2 from user M-bM-^@M-^\johnM-bM-^@M-^], if PermitRootLogin is set to M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^]: tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john Since an SSH-based setup entails a fair amount of overhead, it may be more suited to temporary setups, such as for wireless VPNs. More permanent VPNs are better provided by tools such as ipsecctl(8) and isakmpd(8). ENVIRONMENT ssh will normally set the following environment variables: DISPLAY The DISPLAY variable indicates the location of the X11 server. It is automatically set by ssh to point to a value of the form M-bM-^@M-^\hostname:nM-bM-^@M-^], where M-bM-^@M-^\hostnameM-bM-^@M-^] indicates the host where the shell runs, and M-bM-^@M-^XnM-bM-^@M-^Y is an integer M-bM-^IM-% 1. ssh uses this special value to forward X11 connections over the secure channel. The user should normally not set DISPLAY explicitly, as that will render the X11 connection insecure (and will require the user to manually copy any required authorization cookies). HOME Set to the path of the user's home directory. LOGNAME Synonym for USER; set for compatibility with systems that use this variable. MAIL Set to the path of the user's mailbox. PATH Set to the default PATH, as specified when compiling ssh. SSH_ASKPASS If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11 window to read the passphrase. This is particularly useful when calling ssh from a .xsession or related script. (Note that on some machines it may be necessary to redirect the input from /dev/null to make this work.) SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to communicate with the agent. SSH_CONNECTION Identifies the client and server ends of the connection. The variable contains four space- separated values: client IP address, client port number, server IP address, and server port number. SSH_ORIGINAL_COMMAND This variable contains the original command line if a forced command is executed. It can be used to extract the original arguments. SSH_TTY This is set to the name of the tty (path to the device) associated with the current shell or command. If the current session has no tty, this variable is not set. TZ This variable is set to indicate the present time zone if it was set when the daemon was started (i.e. the daemon passes the value on to new connections). USER Set to the name of the user logging in. Additionally, ssh reads ~/.ssh/environment, and adds lines of the format M-bM-^@M-^\VARNAME=valueM-bM-^@M-^] to the environment if the file exists and users are allowed to change their environment. For more information, see the PermitUserEnvironment option in sshd_config(5). FILES ~/.rhosts This file is used for host-based authentication (see above). On some machines this file may need to be world-readable if the user's home directory is on an NFS partition, because sshd(8) reads it as root. Additionally, this file must be owned by the user, and must not have write permissions for anyone else. The recommended permission for most machines is read/write for the user, and not accessible by others. ~/.shosts This file is used in exactly the same way as .rhosts, but allows host-based authentication without permitting login with rlogin/rsh. ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. ~/.ssh/authorized_keys Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described in the sshd(8) manual page. This file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. ~/.ssh/config This is the per-user configuration file. The file format and configuration options are described in ssh_config(5). Because of the potential for abuse, this file must have strict permissions: read/write for the user, and not writable by others. ~/.ssh/environment Contains additional definitions for environment variables; see ENVIRONMENT, above. ~/.ssh/identity ~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 ~/.ssh/id_rsa Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not accessible by others (read/write/execute). ssh will simply ignore a private key file if it is accessible by others. It is possible to specify a passphrase when generating the key which will be used to encrypt the sensitive part of this file using 3DES. ~/.ssh/identity.pub ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. See sshd(8) for further details of the format of this file. ~/.ssh/rc Commands in this file are executed by ssh when the user logs in, just before the user's shell (or command) is started. See the sshd(8) manual page for more information. /etc/hosts.equiv This file is for host-based authentication (see above). It should only be writable by root. /etc/shosts.equiv This file is used in exactly the same way as hosts.equiv, but allows host-based authentication without permitting login with rlogin/rsh. /etc/ssh/ssh_config Systemwide configuration file. The file format and configuration options are described in ssh_config(5). /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are used for host-based authentication. /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the organization. It should be world-readable. See sshd(8) for further details of the format of this file. /etc/ssh/sshrc Commands in this file are executed by ssh when the user logs in, just before the user's shell (or command) is started. See the sshd(8) manual page for more information. EXIT STATUS ssh exits with the exit status of the remote command or with 255 if an error occurred. SEE ALSO scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1), tun(4), ssh_config(5), ssh-keysign(8), sshd(8) STANDARDS S. Lehtinen and C. Lonvick, The Secure Shell (SSH) Protocol Assigned Numbers, RFC 4250, January 2006. T. Ylonen and C. Lonvick, The Secure Shell (SSH) Protocol Architecture, RFC 4251, January 2006. T. Ylonen and C. Lonvick, The Secure Shell (SSH) Authentication Protocol, RFC 4252, January 2006. T. Ylonen and C. Lonvick, The Secure Shell (SSH) Transport Layer Protocol, RFC 4253, January 2006. T. Ylonen and C. Lonvick, The Secure Shell (SSH) Connection Protocol, RFC 4254, January 2006. J. Schlyter and W. Griffin, Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints, RFC 4255, January 2006. F. Cusack and M. Forssen, Generic Message Exchange Authentication for the Secure Shell Protocol (SSH), RFC 4256, January 2006. J. Galbraith and P. Remaker, The Secure Shell (SSH) Session Channel Break Extension, RFC 4335, January 2006. M. Bellare, T. Kohno, and C. Namprempre, The Secure Shell (SSH) Transport Layer Encryption Modes, RFC 4344, January 2006. B. Harris, Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol, RFC 4345, January 2006. M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006. J. Galbraith and R. Thayer, The Secure Shell (SSH) Public Key File Format, RFC 4716, November 2006. D. Stebila and J. Green, Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer, RFC 5656, December 2009. A. Perrig and D. Song, Hash Visualization: a New Technique to improve Real-World Security, 1999, International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99). AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 openssh-7.2p2/sshd.0010064400017500001750000001037401267007033000124770ustar00djmdjmSSHD(8) System Manager's Manual SSHD(8) NAME sshd M-bM-^@M-^S OpenSSH SSH daemon SYNOPSIS sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_certificate_file] [-E log_file] [-f config_file] [-g login_grace_time] [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len] DESCRIPTION sshd (OpenSSH Daemon) is the daemon program for ssh(1). Together these programs replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure network. sshd listens for connections from clients. It is normally started at boot from /etc/rc. It forks a new daemon for each incoming connection. The forked daemons handle key exchange, encryption, authentication, command execution, and data exchange. sshd can be configured using command-line options or a configuration file (by default sshd_config(5)); command-line options override values specified in the configuration file. sshd rereads its configuration file when it receives a hangup signal, SIGHUP, by executing itself with the name and options it was started with, e.g. /usr/sbin/sshd. The options are as follows: -4 Forces sshd to use IPv4 addresses only. -6 Forces sshd to use IPv6 addresses only. -b bits Specifies the number of bits in the ephemeral protocol version 1 server key (default 1024). -C connection_spec Specify the connection parameters to use for the -T extended test mode. If provided, any Match directives in the configuration file that would apply to the specified user, host, and address will be set before the configuration is written to standard output. The connection parameters are supplied as keyword=value pairs. The keywords are M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and M-bM-^@M-^\addrM-bM-^@M-^]. All are required and may be supplied in any order, either with multiple -C options or as a comma-separated list. -c host_certificate_file Specifies a path to a certificate file to identify sshd during key exchange. The certificate file must match a host key file specified using the -h option or the HostKey configuration directive. -D When this option is specified, sshd will not detach and does not become a daemon. This allows easy monitoring of sshd. -d Debug mode. The server sends verbose debug output to standard error, and does not put itself in the background. The server also will not fork and will only process one connection. This option is only intended for debugging for the server. Multiple -d options increase the debugging level. Maximum is 3. -E log_file Append debug logs to log_file instead of the system log. -e Write debug logs to standard error instead of the system log. -f config_file Specifies the name of the configuration file. The default is /etc/ssh/sshd_config. sshd refuses to start if there is no configuration file. -g login_grace_time Gives the grace time for clients to authenticate themselves (default 120 seconds). If the client fails to authenticate the user within this many seconds, the server disconnects and exits. A value of zero indicates no limit. -h host_key_file Specifies a file from which a host key is read. This option must be given if sshd is not run as root (as the normal host key files are normally not readable by anyone but root). The default is /etc/ssh/ssh_host_key for protocol version 1, and /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key. /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for protocol version 2. It is possible to have multiple host key files for the different protocol versions and host key algorithms. -i Specifies that sshd is being run from inetd(8). If SSH protocol 1 is enabled, sshd should not normally be run from inetd because it needs to generate the server key before it can respond to the client, and this may take some time. Clients may have to wait too long if the key was regenerated every time. -k key_gen_time Specifies how often the ephemeral protocol version 1 server key is regenerated (default 3600 seconds, or one hour). The motivation for regenerating the key fairly often is that the key is not stored anywhere, and after about an hour it becomes impossible to recover the key for decrypting intercepted communications even if the machine is cracked into or physically seized. A value of zero indicates that the key will never be regenerated. -o option Can be used to give options in the format used in the configuration file. This is useful for specifying options for which there is no separate command-line flag. For full details of the options, and their values, see sshd_config(5). -p port Specifies the port on which the server listens for connections (default 22). Multiple port options are permitted. Ports specified in the configuration file with the Port option are ignored when a command-line port is specified. Ports specified using the ListenAddress option override command-line ports. -q Quiet mode. Nothing is sent to the system log. Normally the beginning, authentication, and termination of each connection is logged. -T Extended test mode. Check the validity of the configuration file, output the effective configuration to stdout and then exit. Optionally, Match rules may be applied by specifying the connection parameters using one or more -C options. -t Test mode. Only check the validity of the configuration file and sanity of the keys. This is useful for updating sshd reliably as configuration options may change. -u len This option is used to specify the size of the field in the utmp structure that holds the remote host name. If the resolved host name is longer than len, the dotted decimal value will be used instead. This allows hosts with very long host names that overflow this field to still be uniquely identified. Specifying -u0 indicates that only dotted decimal addresses should be put into the utmp file. -u0 may also be used to prevent sshd from making DNS requests unless the authentication mechanism or configuration requires it. Authentication mechanisms that may require DNS include RhostsRSAAuthentication, HostbasedAuthentication, and using a from="pattern-list" option in a key file. Configuration options that require DNS include using a USER@HOST pattern in AllowUsers or DenyUsers. AUTHENTICATION The OpenSSH SSH daemon supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the Protocol option in sshd_config(5). Protocol 1 should not be used and is only offered to support legacy devices. Each host has a host-specific key, used to identify the host. Partial forward security for protocol 1 is provided through an additional server key, normally 1024 bits, generated when the server starts. This key is normally regenerated every hour if it has been used, and is never stored on disk. Whenever a client connects, the daemon responds with its public host and server keys. The client compares the RSA host key against its own database to verify that it has not changed. The client then generates a 256-bit random number. It encrypts this random number using both the host key and the server key, and sends the encrypted number to the server. Both sides then use this random number as a session key which is used to encrypt all further communications in the session. The rest of the session is encrypted using a conventional cipher, currently Blowfish or 3DES, with 3DES being used by default. The client selects the encryption algorithm to use from those offered by the server. For protocol 2, forward security is provided through a Diffie-Hellman key agreement. This key agreement results in a shared session key. The rest of the session is encrypted using a symmetric cipher, currently 128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES. The client selects the encryption algorithm to use from those offered by the server. Additionally, session integrity is provided through a cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64, umac-128, hmac-ripemd160, hmac-sha2-256 or hmac-sha2-512). Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using host-based authentication, public key authentication, challenge-response authentication, or password authentication. Regardless of the authentication type, the account is checked to ensure that it is accessible. An account is not accessible if it is locked, listed in DenyUsers or its group is listed in DenyGroups . The definition of a locked account is system dependant. Some platforms have their own account database (eg AIX) and some modify the passwd field ( M-bM-^@M-^X*LK*M-bM-^@M-^Y on Solaris and UnixWare, M-bM-^@M-^X*M-bM-^@M-^Y on HP-UX, containing M-bM-^@M-^XNologinM-bM-^@M-^Y on Tru64, a leading M-bM-^@M-^X*LOCKED*M-bM-^@M-^Y on FreeBSD and a leading M-bM-^@M-^X!M-bM-^@M-^Y on most Linuxes). If there is a requirement to disable password authentication for the account while allowing still public-key, then the passwd field should be set to something other than these values (eg M-bM-^@M-^XNPM-bM-^@M-^Y or M-bM-^@M-^X*NP*M-bM-^@M-^Y ). If the client successfully authenticates itself, a dialog for preparing the session is entered. At this time the client may request things like allocating a pseudo-tty, forwarding X11 connections, forwarding TCP connections, or forwarding the authentication agent connection over the secure channel. After this, the client either requests a shell or execution of a command. The sides then enter session mode. In this mode, either side may send data at any time, and such data is forwarded to/from the shell or command on the server side, and the user terminal in the client side. When the user program terminates and all forwarded X11 and other connections have been closed, the server sends command exit status to the client, and both sides exit. LOGIN PROCESS When a user successfully logs in, sshd does the following: 1. If the login is on a tty, and no command has been specified, prints last login time and /etc/motd (unless prevented in the configuration file or by ~/.hushlogin; see the FILES section). 2. If the login is on a tty, records login time. 3. Checks /etc/nologin; if it exists, prints contents and quits (unless root). 4. Changes to run with normal user privileges. 5. Sets up basic environment. 6. Reads the file ~/.ssh/environment, if it exists, and users are allowed to change their environment. See the PermitUserEnvironment option in sshd_config(5). 7. Changes to user's home directory. 8. If ~/.ssh/rc exists and the sshd_config(5) PermitUserRC option is set, runs it; else if /etc/ssh/sshrc exists, runs it; otherwise runs xauth. The M-bM-^@M-^\rcM-bM-^@M-^] files are given the X11 authentication protocol and cookie in standard input. See SSHRC, below. 9. Runs user's shell or command. All commands are run under the user's login shell as specified in the system password database. SSHRC If the file ~/.ssh/rc exists, sh(1) runs it after reading the environment files but before starting the user's shell or command. It must not produce any output on stdout; stderr must be used instead. If X11 forwarding is in use, it will receive the "proto cookie" pair in its standard input (and DISPLAY in its environment). The script must call xauth(1) because sshd will not run xauth automatically to add X11 cookies. The primary purpose of this file is to run any initialization routines which may be needed before the user's home directory becomes accessible; AFS is a particular example of such an environment. This file will probably contain some initialization code followed by something similar to: if read proto cookie && [ -n "$DISPLAY" ]; then if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then # X11UseLocalhost=yes echo add unix:`echo $DISPLAY | cut -c11-` $proto $cookie else # X11UseLocalhost=no echo add $DISPLAY $proto $cookie fi | xauth -q - fi If this file does not exist, /etc/ssh/sshrc is run, and if that does not exist either, xauth is used to add the cookie. AUTHORIZED_KEYS FILE FORMAT AuthorizedKeysFile specifies the files containing public keys for public key authentication; if this option is not specified, the default is ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2. Each line of the file contains one key (empty lines and lines starting with a M-bM-^@M-^X#M-bM-^@M-^Y are ignored as comments). Protocol 1 public keys consist of the following space-separated fields: options, bits, exponent, modulus, comment. Protocol 2 public key consist of: options, keytype, base64-encoded key, comment. The options field is optional; its presence is determined by whether the line starts with a number or not (the options field never starts with a number). The bits, exponent, modulus, and comment fields give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). For protocol version 2 the keytype is M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or M-bM-^@M-^\ssh-rsaM-bM-^@M-^]. Note that lines in this file are usually several hundred bytes long (because of the size of the public key encoding) up to a limit of 8 kilobytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16 kilobits. You don't want to type them in; instead, copy the identity.pub, id_dsa.pub, id_ecdsa.pub, id_ed25519.pub, or the id_rsa.pub file and edit it. sshd enforces a minimum RSA key modulus size for protocol 1 and protocol 2 keys of 768 bits. The options (if present) consist of comma-separated option specifications. No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): agent-forwarding Enable authentication agent forwarding previously disabled by the restrict option. cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user authentication. Certificates may encode access restrictions similar to these key options. If both certificate restrictions and key options are present, the most restrictive union of the two is applied. command="command" Specifies that the command is executed whenever this key is used for authentication. The command supplied by the user (if any) is ignored. The command is run on a pty if the client requests a pty; otherwise it is run without a tty. If an 8-bit clean channel is required, one must not request a pty or should specify no-pty. A quote may be included in the command by quoting it with a backslash. This option might be useful to restrict certain public keys to perform just a specific operation. An example might be a key that permits remote backups but nothing else. Note that the client may specify TCP and/or X11 forwarding unless they are explicitly prohibited. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Note that this option applies to shell, command or subsystem execution. Also note that this command may be superseded by either a sshd_config(5) ForceCommand directive or a command embedded in a certificate. environment="NAME=value" Specifies that the string is to be added to the environment when logging in using this key. Environment variables set this way override other default environment values. Multiple options of this type are permitted. Environment processing is disabled by default and is controlled via the PermitUserEnvironment option. This option is automatically disabled if UseLogin is enabled. from="pattern-list" Specifies that in addition to public key authentication, either the canonical name of the remote host or its IP address must be present in the comma-separated list of patterns. See PATTERNS in ssh_config(5) for more information on patterns. In addition to the wildcard matching that may be applied to hostnames or addresses, a from stanza may match IP addresses using CIDR address/masklen notation. The purpose of this option is to optionally increase security: public key authentication by itself does not trust the network or name servers or anything (but the key); however, if somebody somehow steals the key, the key permits an intruder to log in from anywhere in the world. This additional option makes using a stolen key more difficult (name servers and/or routers would have to be compromised in addition to just the key). no-agent-forwarding Forbids authentication agent forwarding when this key is used for authentication. no-port-forwarding Forbids TCP forwarding when this key is used for authentication. Any port forward requests by the client will return an error. This might be used, e.g. in connection with the command option. no-pty Prevents tty allocation (a request to allocate a pty will fail). no-user-rc Disables execution of ~/.ssh/rc. no-X11-forwarding Forbids X11 forwarding when this key is used for authentication. Any X11 forward requests by the client will return an error. permitopen="host:port" Limit local port forwarding with ssh(1) -L such that it may only connect to the specified host and port. IPv6 addresses can be specified by enclosing the address in square brackets. Multiple permitopen options may be applied separated by commas. No pattern matching is performed on the specified hostnames, they must be literal domains or addresses. A port specification of * matches any port. port-forwarding Enable port forwarding previously disabled by the restrict principals="principals" On a cert-authority line, specifies allowed principals for certificate authentication as a comma-separated list. At least one name from the list must appear in the certificate's list of principals for the certificate to be accepted. This option is ignored for keys that are not marked as trusted certificate signers using the cert-authority option. pty Permits tty allocation previously disabled by the restrict option. restrict Enable all restrictions, i.e. disable port, agent and X11 forwarding, as well as disabling PTY allocation and execution of ~/.ssh/rc. If any future restriction capabilities are added to authorized_keys files they will be included in this set. tunnel="n" Force a tun(4) device on the server. Without this option, the next available device will be used if the client requests a tunnel. user-rc Enables execution of ~/.ssh/rc previously disabled by the restrict option. X11-forwarding Permits X11 forwarding previously disabled by the restrict option. An example authorized_keys file: # Comments allowed at start of line ssh-rsa AAAAB3Nza...LiPk== user@example.net from="*.sales.example.net,!pc.sales.example.net" ssh-rsa AAAAB2...19Q== john@example.net command="dump /home",no-pty,no-port-forwarding ssh-dss AAAAC3...51R== example.net permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss AAAAB5...21S== tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== user@example.net restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5== user@example.net SSH_KNOWN_HOSTS FILE FORMAT The /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts files contain host public keys for all known hosts. The global file should be prepared by the administrator (optional), and the per-user file is maintained automatically: whenever the user connects from an unknown host, its key is added to the per-user file. Each line in these files contains the following fields: markers (optional), hostnames, bits, exponent, modulus, comment. The fields are separated by spaces. The marker is optional, but if it is present then it must be one of M-bM-^@M-^\@cert-authorityM-bM-^@M-^], to indicate that the line contains a certification authority (CA) key, or M-bM-^@M-^\@revokedM-bM-^@M-^], to indicate that the key contained on the line is revoked and must not ever be accepted. Only one marker should be used on a key line. Hostnames is a comma-separated list of patterns (M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name (when authenticating a server). A pattern may also be preceded by M-bM-^@M-^X!M-bM-^@M-^Y to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. A hostname or address may optionally be enclosed within M-bM-^@M-^X[M-bM-^@M-^Y and M-bM-^@M-^X]M-bM-^@M-^Y brackets then followed by M-bM-^@M-^X:M-bM-^@M-^Y and a non-standard port number. Alternately, hostnames may be stored in a hashed form which hides host names and addresses should the file's contents be disclosed. Hashed hostnames start with a M-bM-^@M-^X|M-bM-^@M-^Y character. Only one hashed hostname may appear on a single line and none of the above negation or wildcard operators may be applied. Bits, exponent, and modulus are taken directly from the RSA host key; they can be obtained, for example, from /etc/ssh/ssh_host_key.pub. The optional comment field continues to the end of the line, and is not used. Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are ignored as comments. When performing host authentication, authentication is accepted if any matching line has the proper key; either one that matches exactly or, if the server has presented a certificate for authentication, the key of the certification authority that signed the certificate. For a key to be trusted as a certification authority, it must use the M-bM-^@M-^\@cert-authorityM-bM-^@M-^] marker described above. The known hosts file also provides a facility to mark keys as revoked, for example when it is known that the associated private key has been stolen. Revoked keys are specified by including the M-bM-^@M-^\@revokedM-bM-^@M-^] marker at the beginning of the key line, and are never accepted for authentication or as certification authorities, but instead will produce a warning from ssh(1) when they are encountered. It is permissible (but not recommended) to have several lines or different host keys for the same names. This will inevitably happen when short forms of host names from different domains are put in the file. It is possible that the files contain conflicting information; authentication is accepted if valid information can be found from either file. Note that the lines in these files are typically hundreds of characters long, and you definitely don't want to type in the host keys by hand. Rather, generate them by a script, ssh-keyscan(1) or by taking /etc/ssh/ssh_host_key.pub and adding the host names at the front. ssh-keygen(1) also offers some basic automated editing for ~/.ssh/known_hosts including removing hosts matching a host name and converting all host names to their hashed representations. An example ssh_known_hosts file: # Comments allowed at start of line closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....= # A hashed hostname |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa AAAA1234.....= # A revoked key @revoked * ssh-rsa AAAAB5W... # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... FILES ~/.hushlogin This file is used to suppress printing the last login time and /etc/motd, if PrintLastLog and PrintMotd, respectively, are enabled. It does not suppress printing of the banner specified by Banner. ~/.rhosts This file is used for host-based authentication (see ssh(1) for more information). On some machines this file may need to be world-readable if the user's home directory is on an NFS partition, because sshd reads it as root. Additionally, this file must be owned by the user, and must not have write permissions for anyone else. The recommended permission for most machines is read/write for the user, and not accessible by others. ~/.shosts This file is used in exactly the same way as .rhosts, but allows host-based authentication without permitting login with rlogin/rsh. ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. ~/.ssh/authorized_keys Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. If this file, the ~/.ssh directory, or the user's home directory are writable by other users, then the file could be modified or replaced by unauthorized users. In this case, sshd will not allow it to be used unless the StrictModes option has been set to M-bM-^@M-^\noM-bM-^@M-^]. ~/.ssh/environment This file is read into the environment at login (if it exists). It can only contain empty lines, comment lines (that start with M-bM-^@M-^X#M-bM-^@M-^Y), and assignment lines of the form name=value. The file should be writable only by the user; it need not be readable by anyone else. Environment processing is disabled by default and is controlled via the PermitUserEnvironment option. ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. The format of this file is described above. This file should be writable only by root/the owner and can, but need not be, world-readable. ~/.ssh/rc Contains initialization routines to be run before the user's home directory becomes accessible. This file should be writable only by the user, and need not be readable by anyone else. /etc/hosts.equiv This file is for host-based authentication (see ssh(1)). It should only be writable by root. /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange" key exchange method. The file format is described in moduli(5). If no usable groups are found in this file then fixed internal groups will be used. /etc/motd See motd(5). /etc/nologin If this file exists, sshd refuses to let anyone except root log in. The contents of the file are displayed to anyone trying to log in, and non-root connections are refused. The file should be world-readable. /etc/shosts.equiv This file is used in exactly the same way as hosts.equiv, but allows host-based authentication without permitting login with rlogin/rsh. /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys. These files should only be owned by root, readable only by root, and not accessible to others. Note that sshd does not start if these files are group/world-accessible. /etc/ssh/ssh_host_key.pub /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_rsa_key.pub These files contain the public parts of the host keys. These files should be world-readable but writable only by root. Their contents should match the respective private parts. These files are not really used for anything; they are provided for the convenience of the user so their contents can be copied to known hosts files. These files are created using ssh-keygen(1). /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the organization. The format of this file is described above. This file should be writable only by root/the owner and should be world-readable. /etc/ssh/sshd_config Contains configuration data for sshd. The file format and configuration options are described in sshd_config(5). /etc/ssh/sshrc Similar to ~/.ssh/rc, it can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. /var/empty chroot(2) directory used by sshd during privilege separation in the pre-authentication phase. The directory should not contain any files and must be owned by root and not group or world- writable. /var/run/sshd.pid Contains the process ID of the sshd listening for connections (if there are several daemons running concurrently for different ports, this contains the process ID of the one started last). The content of this file is not sensitive; it can be world- readable. SEE ALSO scp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1), chroot(2), login.conf(5), moduli(5), sshd_config(5), inetd(8), sftp-server(8) AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 openssh-7.2p2/sftp-server.0010064400017500001750000000103461267007033000140150ustar00djmdjmSFTP-SERVER(8) System Manager's Manual SFTP-SERVER(8) NAME sftp-server M-bM-^@M-^S SFTP server subsystem SYNOPSIS sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level] [-P blacklisted_requests] [-p whitelisted_requests] [-u umask] sftp-server -Q protocol_feature DESCRIPTION sftp-server is a program that speaks the server side of SFTP protocol to stdout and expects client requests from stdin. sftp-server is not intended to be called directly, but from sshd(8) using the Subsystem option. Command-line flags to sftp-server should be specified in the Subsystem declaration. See sshd_config(5) for more information. Valid options are: -d start_directory specifies an alternate starting directory for users. The pathname may contain the following tokens that are expanded at runtime: %% is replaced by a literal '%', %d is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. The default is to use the user's home directory. This option is useful in conjunction with the sshd_config(5) ChrootDirectory option. -e Causes sftp-server to print logging information to stderr instead of syslog for debugging. -f log_facility Specifies the facility code that is used when logging messages from sftp-server. The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. -h Displays sftp-server usage information. -l log_level Specifies which messages will be logged by sftp-server. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions that sftp-server performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. -P blacklisted_requests Specify a comma-separated list of SFTP protocol requests that are banned by the server. sftp-server will reply to any blacklisted request with a failure. The -Q flag can be used to determine the supported request types. If both a blacklist and a whitelist are specified, then the blacklist is applied before the whitelist. -p whitelisted_requests Specify a comma-separated list of SFTP protocol requests that are permitted by the server. All request types that are not on the whitelist will be logged and replied to with a failure message. Care must be taken when using this feature to ensure that requests made implicitly by SFTP clients are permitted. -Q protocol_feature Query protocol features supported by sftp-server. At present the only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be used for black or whitelisting (flags -P and -p respectively). -R Places this instance of sftp-server into a read-only mode. Attempts to open files for writing, as well as other operations that change the state of the filesystem, will be denied. -u umask Sets an explicit umask(2) to be applied to newly-created files and directories, instead of the user's default mask. On some systems, sftp-server must be able to access /dev/log for logging to work, and use of sftp-server in a chroot configuration therefore requires that syslogd(8) establish a logging socket inside the chroot directory. SEE ALSO sftp(1), ssh(1), sshd_config(5), sshd(8) T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-02.txt, October 2001, work in progress material. HISTORY sftp-server first appeared in OpenBSD 2.8. AUTHORS Markus Friedl OpenBSD 5.9 December 11, 2014 OpenBSD 5.9 openssh-7.2p2/sftp.0010064400017500001750000000364041267007033000125140ustar00djmdjmSFTP(1) General Commands Manual SFTP(1) NAME sftp M-bM-^@M-^S secure file transfer program SYNOPSIS sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host DESCRIPTION sftp is an interactive file transfer program, similar to ftp(1), which performs all operations over an encrypted ssh(1) transport. It may also use many features of ssh, such as public key authentication and compression. sftp connects and logs into the specified host, then enters an interactive command mode. The second usage format will retrieve files automatically if a non- interactive authentication method is used; otherwise it will do so after successful interactive authentication. The third usage format allows sftp to start in a remote directory. The final usage format allows for automated sessions using the -b option. In such cases, it is necessary to configure non-interactive authentication to obviate the need to enter a password at connection time (see sshd(8) and ssh-keygen(1) for details). Since some usage formats use colon characters to delimit host names from path names, IPv6 addresses must be enclosed in square brackets to avoid ambiguity. The options are as follows: -1 Specify the use of protocol version 1. -2 Specify the use of protocol version 2. -4 Forces sftp to use IPv4 addresses only. -6 Forces sftp to use IPv6 addresses only. -a Attempt to continue interrupted transfers rather than overwriting existing partial or complete copies of files. If the partial contents differ from those being transferred, then the resultant file is likely to be corrupt. -B buffer_size Specify the size of the buffer that sftp uses when transferring files. Larger buffers require fewer round trips at the cost of higher memory consumption. The default is 32768 bytes. -b batchfile Batch mode reads a series of commands from an input batchfile instead of stdin. Since it lacks user interaction it should be used in conjunction with non-interactive authentication. A batchfile of M-bM-^@M-^X-M-bM-^@M-^Y may be used to indicate standard input. sftp will abort if any of the following commands fail: get, put, reget, reput, rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, chown, chgrp, lpwd, df, symlink, and lmkdir. Termination on error can be suppressed on a command by command basis by prefixing the command with a M-bM-^@M-^X-M-bM-^@M-^Y character (for example, -rm /tmp/blah*). -C Enables compression (via ssh's -C flag). -c cipher Selects the cipher to use for encrypting the data transfers. This option is directly passed to ssh(1). -D sftp_server_path Connect directly to a local sftp server (rather than via ssh(1)). This option may be useful in debugging the client and server. -F ssh_config Specifies an alternative per-user configuration file for ssh(1). This option is directly passed to ssh(1). -f Requests that files be flushed to disk immediately after transfer. When uploading files, this feature is only enabled if the server implements the "fsync@openssh.com" extension. -i identity_file Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to ssh(1). -l limit Limits the used bandwidth, specified in Kbit/s. -o ssh_option Can be used to pass options to ssh in the format used in ssh_config(5). This is useful for specifying options for which there is no separate sftp command-line flag. For example, to specify an alternate port use: sftp -oPort=24. For full details of the options listed below, and their possible values, see ssh_config(5). AddressFamily BatchMode BindAddress CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher Ciphers Compression CompressionLevel ConnectionAttempts ConnectTimeout ControlMaster ControlPath ControlPersist GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials HashKnownHosts Host HostbasedAuthentication HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName IdentityFile IdentitiesOnly IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand PubkeyAuthentication RekeyLimit RhostsRSAAuthentication RSAAuthentication SendEnv ServerAliveInterval ServerAliveCountMax StrictHostKeyChecking TCPKeepAlive UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile VerifyHostKeyDNS -P port Specifies the port to connect to on the remote host. -p Preserves modification times, access times, and modes from the original files transferred. -q Quiet mode: disables the progress meter as well as warning and diagnostic messages from ssh(1). -R num_requests Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. The default is 64 outstanding requests. -r Recursively copy entire directories when uploading and downloading. Note that sftp does not follow symbolic links encountered in the tree traversal. -S program Name of the program to use for the encrypted connection. The program must understand ssh(1) options. -s subsystem | sftp_server Specifies the SSH2 subsystem or the path for an sftp server on the remote host. A path is useful for using sftp over protocol version 1, or when the remote sshd(8) does not have an sftp subsystem configured. -v Raise logging level. This option is also passed to ssh. INTERACTIVE COMMANDS Once in interactive mode, sftp understands a set of commands similar to those of ftp(1). Commands are case insensitive. Pathnames that contain spaces must be enclosed in quotes. Any special characters contained within pathnames that are recognized by glob(3) must be escaped with backslashes (M-bM-^@M-^X\M-bM-^@M-^Y). bye Quit sftp. cd path Change remote directory to path. chgrp grp path Change group of file path to grp. path may contain glob(3) characters and may match multiple files. grp must be a numeric GID. chmod mode path Change permissions of file path to mode. path may contain glob(3) characters and may match multiple files. chown own path Change owner of file path to own. path may contain glob(3) characters and may match multiple files. own must be a numeric UID. df [-hi] [path] Display usage information for the filesystem holding the current directory (or path if specified). If the -h flag is specified, the capacity information will be displayed using "human-readable" suffixes. The -i flag requests display of inode information in addition to capacity information. This command is only supported on servers that implement the M-bM-^@M-^\statvfs@openssh.comM-bM-^@M-^] extension. exit Quit sftp. get [-afPpr] remote-path [local-path] Retrieve the remote-path and store it on the local machine. If the local path name is not specified, it is given the same name it has on the remote machine. remote-path may contain glob(3) characters and may match multiple files. If it does and local-path is specified, then local-path must specify a directory. If the -a flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the local file matches the remote copy. If the remote file contents differ from the partial local copy then the resultant file is likely to be corrupt. If the -f flag is specified, then fsync(2) will be called after the file transfer has completed to flush the file to disk. If either the -P or -p flag is specified, then full file permissions and access times are copied too. If the -r flag is specified then directories will be copied recursively. Note that sftp does not follow symbolic links when performing recursive transfers. help Display help text. lcd path Change local directory to path. lls [ls-options [path]] Display local directory listing of either path or current directory if path is not specified. ls-options may contain any flags supported by the local system's ls(1) command. path may contain glob(3) characters and may match multiple files. lmkdir path Create local directory specified by path. ln [-s] oldpath newpath Create a link from oldpath to newpath. If the -s flag is specified the created link is a symbolic link, otherwise it is a hard link. lpwd Print local working directory. ls [-1afhlnrSt] [path] Display a remote directory listing of either path or the current directory if path is not specified. path may contain glob(3) characters and may match multiple files. The following flags are recognized and alter the behaviour of ls accordingly: -1 Produce single columnar output. -a List files beginning with a dot (M-bM-^@M-^X.M-bM-^@M-^Y). -f Do not sort the listing. The default sort order is lexicographical. -h When used with a long format option, use unit suffixes: Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce the number of digits to four or fewer using powers of 2 for sizes (K=1024, M=1048576, etc.). -l Display additional details including permissions and ownership information. -n Produce a long listing with user and group information presented numerically. -r Reverse the sort order of the listing. -S Sort the listing by file size. -t Sort the listing by last modification time. lumask umask Set local umask to umask. mkdir path Create remote directory specified by path. progress Toggle display of progress meter. put [-afPpr] local-path [remote-path] Upload local-path and store it on the remote machine. If the remote path name is not specified, it is given the same name it has on the local machine. local-path may contain glob(3) characters and may match multiple files. If it does and remote-path is specified, then remote-path must specify a directory. If the -a flag is specified, then attempt to resume partial transfers of existing files. Note that resumption assumes that any partial copy of the remote file matches the local copy. If the local file contents differ from the remote local copy then the resultant file is likely to be corrupt. If the -f flag is specified, then a request will be sent to the server to call fsync(2) after the file has been transferred. Note that this is only supported by servers that implement the "fsync@openssh.com" extension. If either the -P or -p flag is specified, then full file permissions and access times are copied too. If the -r flag is specified then directories will be copied recursively. Note that sftp does not follow symbolic links when performing recursive transfers. pwd Display remote working directory. quit Quit sftp. reget [-Ppr] remote-path [local-path] Resume download of remote-path. Equivalent to get with the -a flag set. reput [-Ppr] [local-path] remote-path Resume upload of [local-path]. Equivalent to put with the -a flag set. rename oldpath newpath Rename remote file from oldpath to newpath. rm path Delete remote file specified by path. rmdir path Remove remote directory specified by path. symlink oldpath newpath Create a symbolic link from oldpath to newpath. version Display the sftp protocol version. !command Execute command in local shell. ! Escape to local shell. ? Synonym for help. SEE ALSO ftp(1), ls(1), scp(1), ssh(1), ssh-add(1), ssh-keygen(1), glob(3), ssh_config(5), sftp-server(8), sshd(8) T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. OpenBSD 5.9 September 25, 2015 OpenBSD 5.9 openssh-7.2p2/ssh-keysign.0010064400017500001750000000035001267007033000137730ustar00djmdjmSSH-KEYSIGN(8) System Manager's Manual SSH-KEYSIGN(8) NAME ssh-keysign M-bM-^@M-^S ssh helper program for host-based authentication SYNOPSIS ssh-keysign DESCRIPTION ssh-keysign is used by ssh(1) to access the local host keys and generate the digital signature required during host-based authentication. ssh-keysign is disabled by default and can only be enabled in the global client configuration file /etc/ssh/ssh_config by setting EnableSSHKeysign to M-bM-^@M-^\yesM-bM-^@M-^]. ssh-keysign is not intended to be invoked by the user, but from ssh(1). See ssh(1) and sshd(8) for more information about host-based authentication. FILES /etc/ssh/ssh_config Controls whether ssh-keysign is enabled. /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They should be owned by root, readable only by root, and not accessible to others. Since they are readable only by root, ssh-keysign must be set-uid root if host-based authentication is used. /etc/ssh/ssh_host_dsa_key-cert.pub /etc/ssh/ssh_host_ecdsa_key-cert.pub /etc/ssh/ssh_host_ed25519_key-cert.pub /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys above. SEE ALSO ssh(1), ssh-keygen(1), ssh_config(5), sshd(8) HISTORY ssh-keysign first appeared in OpenBSD 3.2. AUTHORS Markus Friedl OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 openssh-7.2p2/ssh-pkcs11-helper.0010064400017500001750000000012021267007033000146760ustar00djmdjmSSH-PKCS11-HELPER(8) System Manager's Manual SSH-PKCS11-HELPER(8) NAME ssh-pkcs11-helper M-bM-^@M-^S ssh-agent helper program for PKCS#11 support SYNOPSIS ssh-pkcs11-helper DESCRIPTION ssh-pkcs11-helper is used by ssh-agent(1) to access keys provided by a PKCS#11 token. ssh-pkcs11-helper is not intended to be invoked by the user, but from ssh-agent(1). SEE ALSO ssh(1), ssh-add(1), ssh-agent(1) HISTORY ssh-pkcs11-helper first appeared in OpenBSD 4.7. AUTHORS Markus Friedl OpenBSD 5.9 July 16, 2013 OpenBSD 5.9 openssh-7.2p2/sshd_config.0010064400017500001750000001626241267007033000140320ustar00djmdjmSSHD_CONFIG(5) File Formats Manual SSHD_CONFIG(5) NAME sshd_config M-bM-^@M-^S OpenSSH SSH daemon configuration file SYNOPSIS /etc/ssh/sshd_config DESCRIPTION sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file specified with -f on the command line). The file contains keyword- argument pairs, one per line. Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are interpreted as comments. Arguments may optionally be enclosed in double quotes (") in order to represent arguments containing spaces. The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): AcceptEnv Specifies what environment variables sent by the client will be copied into the session's environ(7). See SendEnv in ssh_config(5) for how to configure the client. The TERM environment variable is always sent whenever the client requests a pseudo-terminal as it is required by the protocol. Variables are specified by name, which may contain the wildcard characters M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y. Multiple environment variables may be separated by whitespace or spread across multiple AcceptEnv directives. Be warned that some environment variables could be used to bypass restricted user environments. For this reason, care should be taken in the use of this directive. The default is not to accept any environment variables. AddressFamily Specifies which address family should be used by sshd(8). Valid arguments are M-bM-^@M-^\anyM-bM-^@M-^], M-bM-^@M-^\inetM-bM-^@M-^] (use IPv4 only), or M-bM-^@M-^\inet6M-bM-^@M-^] (use IPv6 only). The default is M-bM-^@M-^\anyM-bM-^@M-^]. AllowAgentForwarding Specifies whether ssh-agent(1) forwarding is permitted. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling agent forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups. See PATTERNS in ssh_config(5) for more information on patterns. AllowTcpForwarding Specifies whether TCP forwarding is permitted. The available options are M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\allM-bM-^@M-^] to allow TCP forwarding, M-bM-^@M-^\noM-bM-^@M-^] to prevent all TCP forwarding, M-bM-^@M-^\localM-bM-^@M-^] to allow local (from the perspective of ssh(1)) forwarding only or M-bM-^@M-^\remoteM-bM-^@M-^] to allow remote forwarding only. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. AllowStreamLocalForwarding Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. The available options are M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\allM-bM-^@M-^] to allow StreamLocal forwarding, M-bM-^@M-^\noM-bM-^@M-^] to prevent all StreamLocal forwarding, M-bM-^@M-^\localM-bM-^@M-^] to allow local (from the perspective of ssh(1)) forwarding only or M-bM-^@M-^\remoteM-bM-^@M-^] to allow remote forwarding only. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling StreamLocal forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. AllowUsers This keyword can be followed by a list of user name patterns, separated by spaces. If specified, login is allowed only for user names that match one of the patterns. Only user names are valid; a numerical user ID is not recognized. By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups. See PATTERNS in ssh_config(5) for more information on patterns. AuthenticationMethods Specifies the authentication methods that must be successfully completed for a user to be granted access. This option must be followed by one or more comma-separated lists of authentication method names. Successful authentication requires completion of every method in at least one of these lists. For example, an argument of M-bM-^@M-^\publickey,password publickey,keyboard-interactiveM-bM-^@M-^] would require the user to complete public key authentication, followed by either password or keyboard interactive authentication. Only methods that are next in one or more lists are offered at each stage, so for this example, it would not be possible to attempt password or keyboard-interactive authentication before public key. For keyboard interactive authentication it is also possible to restrict authentication to a specific device by appending a colon followed by the device identifier M-bM-^@M-^\bsdauthM-bM-^@M-^], M-bM-^@M-^\pamM-bM-^@M-^], or M-bM-^@M-^\skeyM-bM-^@M-^], depending on the server configuration. For example, M-bM-^@M-^\keyboard-interactive:bsdauthM-bM-^@M-^] would restrict keyboard interactive authentication to the M-bM-^@M-^\bsdauthM-bM-^@M-^] device. If the M-bM-^@M-^\publickeyM-bM-^@M-^] method is listed more than once, sshd(8) verifies that keys that have been used successfully are not reused for subsequent authentications. For example, an AuthenticationMethods of M-bM-^@M-^\publickey,publickeyM-bM-^@M-^] will require successful authentication using two different public keys. This option will yield a fatal error if enabled if protocol 1 is also enabled. Note that each authentication method listed should also be explicitly enabled in the configuration. The default is not to require multiple authentication; successful completion of a single authentication method is sufficient. AuthorizedKeysCommand Specifies a program to be used to look up the user's public keys. The program must be owned by root, not writable by group or others and specified by an absolute path. Arguments to AuthorizedKeysCommand may be provided using the following tokens, which will be expanded at runtime: %% is replaced by a literal '%', %u is replaced by the username being authenticated, %h is replaced by the home directory of the user being authenticated, %t is replaced with the key type offered for authentication, %f is replaced with the fingerprint of the key, and %k is replaced with the key being offered for authentication. If no arguments are specified then the username of the target user will be supplied. The program should produce on standard output zero or more lines of authorized_keys output (see AUTHORIZED_KEYS in sshd(8)). If a key supplied by AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual AuthorizedKeysFile files. By default, no AuthorizedKeysCommand is run. AuthorizedKeysCommandUser Specifies the user under whose account the AuthorizedKeysCommand is run. It is recommended to use a dedicated user that has no other role on the host than running authorized keys commands. If AuthorizedKeysCommand is specified but AuthorizedKeysCommandUser is not, then sshd(8) will refuse to start. AuthorizedKeysFile Specifies the file that contains the public keys that can be used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of sshd(8). AuthorizedKeysFile may contain tokens of the form %T which are substituted during connection setup. The following tokens are defined: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. After expansion, AuthorizedKeysFile is taken to be an absolute path or one relative to the user's home directory. Multiple files may be listed, separated by whitespace. Alternately this option may be set to M-bM-^@M-^\noneM-bM-^@M-^] to skip checking for user keys in files. The default is M-bM-^@M-^\.ssh/authorized_keys .ssh/authorized_keys2M-bM-^@M-^]. AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed certificate principals as per AuthorizedPrincipalsFile. The program must be owned by root, not writable by group or others and specified by an absolute path. Arguments to AuthorizedPrincipalsCommand may be provided using the following tokens, which will be expanded at runtime: %% is replaced by a literal '%', %u is replaced by the username being authenticated and %h is replaced by the home directory of the user being authenticated. The program should produce on standard output zero or more lines of AuthorizedPrincipalsFile output. If either AuthorizedPrincipalsCommand or AuthorizedPrincipalsFile is specified, then certificates offered by the client for authentication must contain a principal that is listed. By default, no AuthorizedPrincipalsCommand is run. AuthorizedPrincipalsCommandUser Specifies the user under whose account the AuthorizedPrincipalsCommand is run. It is recommended to use a dedicated user that has no other role on the host than running authorized principals commands. If AuthorizedPrincipalsCommand is specified but AuthorizedPrincipalsCommandUser is not, then sshd(8) will refuse to start. AuthorizedPrincipalsFile Specifies a file that lists principal names that are accepted for certificate authentication. When using certificates signed by a key listed in TrustedUserCAKeys, this file lists names, one of which must appear in the certificate for it to be accepted for authentication. Names are listed one per line preceded by key options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)). Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored. AuthorizedPrincipalsFile may contain tokens of the form %T which are substituted during connection setup. The following tokens are defined: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. After expansion, AuthorizedPrincipalsFile is taken to be an absolute path or one relative to the user's home directory. The default is M-bM-^@M-^\noneM-bM-^@M-^], i.e. not to use a principals file M-bM-^@M-^S in this case, the username of the user must appear in a certificate's principals list for it to be accepted. Note that AuthorizedPrincipalsFile is only used when authentication proceeds using a CA listed in TrustedUserCAKeys and is not consulted for certification authorities trusted via ~/.ssh/authorized_keys, though the principals= key option offers a similar facility (see sshd(8) for details). Banner The contents of the specified file are sent to the remote user before authentication is allowed. If the argument is M-bM-^@M-^\noneM-bM-^@M-^] then no banner is displayed. By default, no banner is displayed. ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed (e.g. via PAM or through authentication styles supported in login.conf(5)) The default is M-bM-^@M-^\yesM-bM-^@M-^]. ChrootDirectory Specifies the pathname of a directory to chroot(2) to after authentication. At session startup sshd(8) checks that all components of the pathname are root-owned directories which are not writable by any other user or group. After the chroot, sshd(8) changes the working directory to the user's home directory. The pathname may contain the following tokens that are expanded at runtime once the connecting user has been authenticated: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. The ChrootDirectory must contain the necessary files and directories to support the user's session. For an interactive session this requires at least a shell, typically sh(1), and basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4), and tty(4) devices. For file transfer sessions using M-bM-^@M-^\sftpM-bM-^@M-^], no additional configuration of the environment is necessary if the in-process sftp server is used, though sessions which use logging may require /dev/log inside the chroot directory on some operating systems (see sftp-server(8) for details). For safety, it is very important that the directory hierarchy be prevented from modification by other processes on the system (especially those outside the jail). Misconfiguration can lead to unsafe environments which sshd(8) cannot detect. The default is M-bM-^@M-^\noneM-bM-^@M-^], indicating not to chroot(2). Ciphers Specifies the ciphers allowed. Multiple ciphers must be comma- separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified ciphers will be appended to the default set instead of replacing them. The supported ciphers are: 3des-cbc aes128-cbc aes192-cbc aes256-cbc aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com arcfour arcfour128 arcfour256 blowfish-cbc cast128-cbc chacha20-poly1305@openssh.com The default is: chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com The list of available ciphers may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. ClientAliveCountMax Sets the number of client alive messages (see below) which may be sent without sshd(8) receiving any messages back from the client. If this threshold is reached while client alive messages are being sent, sshd will disconnect the client, terminating the session. It is important to note that the use of client alive messages is very different from TCPKeepAlive (below). The client alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by TCPKeepAlive is spoofable. The client alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive. The default value is 3. If ClientAliveInterval (see below) is set to 15, and ClientAliveCountMax is left at the default, unresponsive SSH clients will be disconnected after approximately 45 seconds. ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. Compression Specifies whether compression is allowed, or delayed until the user has authenticated successfully. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\delayedM-bM-^@M-^], or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\delayedM-bM-^@M-^]. DenyGroups This keyword can be followed by a list of group name patterns, separated by spaces. Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups. See PATTERNS in ssh_config(5) for more information on patterns. DenyUsers This keyword can be followed by a list of user name patterns, separated by spaces. Login is disallowed for user names that match one of the patterns. Only user names are valid; a numerical user ID is not recognized. By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups. See PATTERNS in ssh_config(5) for more information on patterns. FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. ForceCommand Forces the execution of the command specified by ForceCommand, ignoring any command supplied by the client and ~/.ssh/rc if present. The command is invoked by using the user's login shell with the -c option. This applies to shell, command, or subsystem execution. It is most useful inside a Match block. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Specifying a command of M-bM-^@M-^\internal-sftpM-bM-^@M-^] will force the use of an in-process sftp server that requires no support files when used with ChrootDirectory. The default is M-bM-^@M-^\noneM-bM-^@M-^]. GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. By default, sshd(8) binds remote port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to connect. The argument may be M-bM-^@M-^\noM-bM-^@M-^] to force remote port forwardings to be available to the local host only, M-bM-^@M-^\yesM-bM-^@M-^] to force remote port forwardings to bind to the wildcard address, or M-bM-^@M-^\clientspecifiedM-bM-^@M-^] to allow the client to select the address to which the forwarding is bound. The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If set to M-bM-^@M-^\yesM-bM-^@M-^] then the client must authenticate against the host service on the current hostname. If set to M-bM-^@M-^\noM-bM-^@M-^] then the client may authenticate against any service key stored in the machine's default store. This facility is provided to assist with operation on multi homed machines. The default is M-bM-^@M-^\yesM-bM-^@M-^]. HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa The -Q option of ssh(1) may be used to list supported key types. HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed (host-based authentication). The default is M-bM-^@M-^\noM-bM-^@M-^]. HostbasedUsesNameFromPacketOnly Specifies whether or not the server will attempt to perform a reverse name lookup when matching the name in the ~/.shosts, ~/.rhosts, and /etc/hosts.equiv files during HostbasedAuthentication. A setting of M-bM-^@M-^\yesM-bM-^@M-^] means that sshd(8) uses the name supplied by the client rather than attempting to resolve the name from the TCP connection itself. The default is M-bM-^@M-^\noM-bM-^@M-^]. HostCertificate Specifies a file containing a public host certificate. The certificate's public key must match a private host key already specified by HostKey. The default behaviour of sshd(8) is not to load any certificates. HostKey Specifies a file containing a private host key used by SSH. The default is /etc/ssh/ssh_host_key for protocol version 1, and /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key, /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for protocol version 2. Note that sshd(8) will refuse to use a file if it is group/world- accessible and that the HostKeyAlgorithms option restricts which of the keys are actually used by sshd(8). It is possible to have multiple host key files. M-bM-^@M-^\rsa1M-bM-^@M-^] keys are used for version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^] or M-bM-^@M-^\rsaM-bM-^@M-^] are used for version 2 of the SSH protocol. It is also possible to specify public host key files instead. In this case operations on the private key will be delegated to an ssh-agent(1). HostKeyAgent Identifies the UNIX-domain socket used to communicate with an agent that has access to the private host keys. If M-bM-^@M-^\SSH_AUTH_SOCKM-bM-^@M-^] is specified, the location of the socket will be read from the SSH_AUTH_SOCK environment variable. HostKeyAlgorithms Specifies the host key algorithms that the server offers. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa The list of available key types may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\keyM-bM-^@M-^]. IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in RhostsRSAAuthentication or HostbasedAuthentication. /etc/hosts.equiv and /etc/shosts.equiv are still used. The default is M-bM-^@M-^\yesM-bM-^@M-^]. IgnoreUserKnownHosts Specifies whether sshd(8) should ignore the user's ~/.ssh/known_hosts during RhostsRSAAuthentication or HostbasedAuthentication. The default is M-bM-^@M-^\noM-bM-^@M-^]. IPQoS Specifies the IPv4 type-of-service or DSCP class for the connection. Accepted values are M-bM-^@M-^\af11M-bM-^@M-^], M-bM-^@M-^\af12M-bM-^@M-^], M-bM-^@M-^\af13M-bM-^@M-^], M-bM-^@M-^\af21M-bM-^@M-^], M-bM-^@M-^\af22M-bM-^@M-^], M-bM-^@M-^\af23M-bM-^@M-^], M-bM-^@M-^\af31M-bM-^@M-^], M-bM-^@M-^\af32M-bM-^@M-^], M-bM-^@M-^\af33M-bM-^@M-^], M-bM-^@M-^\af41M-bM-^@M-^], M-bM-^@M-^\af42M-bM-^@M-^], M-bM-^@M-^\af43M-bM-^@M-^], M-bM-^@M-^\cs0M-bM-^@M-^], M-bM-^@M-^\cs1M-bM-^@M-^], M-bM-^@M-^\cs2M-bM-^@M-^], M-bM-^@M-^\cs3M-bM-^@M-^], M-bM-^@M-^\cs4M-bM-^@M-^], M-bM-^@M-^\cs5M-bM-^@M-^], M-bM-^@M-^\cs6M-bM-^@M-^], M-bM-^@M-^\cs7M-bM-^@M-^], M-bM-^@M-^\efM-bM-^@M-^], M-bM-^@M-^\lowdelayM-bM-^@M-^], M-bM-^@M-^\throughputM-bM-^@M-^], M-bM-^@M-^\reliabilityM-bM-^@M-^], or a numeric value. This option may take one or two arguments, separated by whitespace. If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is M-bM-^@M-^\lowdelayM-bM-^@M-^] for interactive sessions and M-bM-^@M-^\throughputM-bM-^@M-^] for non-interactive sessions. KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is to use whatever value ChallengeResponseAuthentication is set to (by default M-bM-^@M-^\yesM-bM-^@M-^]). KerberosAuthentication Specifies whether the password provided by the user for PasswordAuthentication will be validated through the Kerberos KDC. To use this option, the server needs a Kerberos servtab which allows the verification of the KDC's identity. The default is M-bM-^@M-^\noM-bM-^@M-^]. KerberosGetAFSToken If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire an AFS token before accessing the user's home directory. The default is M-bM-^@M-^\noM-bM-^@M-^]. KerberosOrLocalPasswd If password authentication through Kerberos fails then the password will be validated via any additional local mechanism such as /etc/passwd. The default is M-bM-^@M-^\yesM-bM-^@M-^]. KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified methods will be appended to the default set instead of replacing them. The supported algorithms are: curve25519-sha256@libssh.org diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 The default is: curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1 The list of available key exchange algorithms may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\kexM-bM-^@M-^]. KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). The purpose of regeneration is to prevent decrypting captured sessions by later breaking into the machine and stealing the keys. The key is never stored anywhere. If the value is 0, the key is never regenerated. The default is 3600 (seconds). ListenAddress Specifies the local addresses sshd(8) should listen on. The following forms may be used: ListenAddress host|IPv4_addr|IPv6_addr ListenAddress host|IPv4_addr:port ListenAddress [host|IPv6_addr]:port If port is not specified, sshd will listen on the address and all Port options specified. The default is to listen on all local addresses. Multiple ListenAddress options are permitted. LoginGraceTime The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. The default is 120 seconds. LogLevel Gives the verbosity level that is used when logging messages from sshd(8). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. Logging with a DEBUG level violates the privacy of users and is not recommended. MACs Specifies the available MAC (message authentication code) algorithms. The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified algorithms will be appended to the default set instead of replacing them. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. The supported MACs are: hmac-md5 hmac-md5-96 hmac-ripemd160 hmac-sha1 hmac-sha1-96 hmac-sha2-256 hmac-sha2-512 umac-64@openssh.com umac-128@openssh.com hmac-md5-etm@openssh.com hmac-md5-96-etm@openssh.com hmac-ripemd160-etm@openssh.com hmac-sha1-etm@openssh.com hmac-sha1-96-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com umac-64-etm@openssh.com umac-128-etm@openssh.com The default is: umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512,hmac-sha1 The list of available MAC algorithms may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\macM-bM-^@M-^]. Match Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. If a keyword appears in multiple Match blocks that are satisfied, only the first instance of the keyword is applied. The arguments to Match are one or more criteria-pattern pairs or the single token All which matches all criteria. The available criteria are User, Group, Host, LocalAddress, LocalPort, and Address. The match patterns may consist of single entries or comma-separated lists and may use the wildcard and negation operators described in the PATTERNS section of ssh_config(5). The patterns in an Address criteria may additionally contain addresses to match in CIDR address/masklen format, e.g. M-bM-^@M-^\192.0.2.0/24M-bM-^@M-^] or M-bM-^@M-^\3ffe:ffff::/32M-bM-^@M-^]. Note that the mask length provided must be consistent with the address - it is an error to specify a mask length that is too long for the address or one with bits set in this host portion of the address. For example, M-bM-^@M-^\192.0.2.0/33M-bM-^@M-^] and M-bM-^@M-^\192.0.2.0/8M-bM-^@M-^] respectively. Only a subset of keywords may be used on the lines following a Match keyword. Available keywords are AcceptEnv, AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, AllowTcpForwarding, AllowUsers, AuthenticationMethods, AuthorizedKeysCommand, AuthorizedKeysCommandUser, AuthorizedKeysFile, AuthorizedPrincipalsCommand, AuthorizedPrincipalsCommandUser, AuthorizedPrincipalsFile, Banner, ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, KbdInteractiveAuthentication, KerberosAuthentication, MaxAuthTries, MaxSessions, PasswordAuthentication, PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes, PubkeyAuthentication, RekeyLimit, RevokedKeys, RhostsRSAAuthentication, RSAAuthentication, StreamLocalBindMask, StreamLocalBindUnlink, TrustedUserCAKeys, X11DisplayOffset, X11Forwarding and X11UseLocalHost. MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. The default is 6. MaxSessions Specifies the maximum number of open shell, login or subsystem (e.g. sftp) sessions permitted per network connection. Multiple sessions may be established by clients that support connection multiplexing. Setting MaxSessions to 1 will effectively disable session multiplexing, whereas setting it to 0 will prevent all shell, login and subsystem sessions while still permitting forwarding. The default is 10. MaxStartups Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections will be dropped until authentication succeeds or the LoginGraceTime expires for a connection. The default is 10:30:100. Alternatively, random early drop can be enabled by specifying the three colon separated values M-bM-^@M-^\start:rate:fullM-bM-^@M-^] (e.g. "10:30:60"). sshd(8) will refuse connection attempts with a probability of M-bM-^@M-^\rate/100M-bM-^@M-^] (30%) if there are currently M-bM-^@M-^\startM-bM-^@M-^] (10) unauthenticated connections. The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches M-bM-^@M-^\fullM-bM-^@M-^] (60). PasswordAuthentication Specifies whether password authentication is allowed. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is M-bM-^@M-^\noM-bM-^@M-^]. PermitOpen Specifies the destinations to which TCP port forwarding is permitted. The forwarding specification must be one of the following forms: PermitOpen host:port PermitOpen IPv4_addr:port PermitOpen [IPv6_addr]:port Multiple forwards may be specified by separating them with whitespace. An argument of M-bM-^@M-^\anyM-bM-^@M-^] can be used to remove all restrictions and permit any forwarding requests. An argument of M-bM-^@M-^\noneM-bM-^@M-^] can be used to prohibit all forwarding requests. By default all port forwarding requests are permitted. PermitRootLogin Specifies whether root can log in using ssh(1). The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\prohibit-passwordM-bM-^@M-^], M-bM-^@M-^\without-passwordM-bM-^@M-^], M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^], or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\prohibit-passwordM-bM-^@M-^]. If this option is set to M-bM-^@M-^\prohibit-passwordM-bM-^@M-^] or M-bM-^@M-^\without-passwordM-bM-^@M-^], password and keyboard-interactive authentication are disabled for root. If this option is set to M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^], root login with public key authentication will be allowed, but only if the command option has been specified (which may be useful for taking remote backups even if root login is normally not allowed). All other authentication methods are disabled for root. If this option is set to M-bM-^@M-^\noM-bM-^@M-^], root is not allowed to log in. PermitTunnel Specifies whether tun(4) device forwarding is allowed. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\point-to-pointM-bM-^@M-^] (layer 3), M-bM-^@M-^\ethernetM-bM-^@M-^] (layer 2), or M-bM-^@M-^\noM-bM-^@M-^]. Specifying M-bM-^@M-^\yesM-bM-^@M-^] permits both M-bM-^@M-^\point-to-pointM-bM-^@M-^] and M-bM-^@M-^\ethernetM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. Independent of this setting, the permissions of the selected tun(4) device must allow access to the user. PermitTTY Specifies whether pty(4) allocation is permitted. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PermitUserEnvironment Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8). The default is M-bM-^@M-^\noM-bM-^@M-^]. Enabling environment processing may enable users to bypass access restrictions in some configurations using mechanisms such as LD_PRELOAD. PermitUserRC Specifies whether any ~/.ssh/rc file is executed. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PidFile Specifies the file that contains the process ID of the SSH daemon, or M-bM-^@M-^\noneM-bM-^@M-^] to not write one. The default is /var/run/sshd.pid. Port Specifies the port number that sshd(8) listens on. The default is 22. Multiple options of this type are permitted. See also ListenAddress. PrintLastLog Specifies whether sshd(8) should print the date and time of the last user login when a user logs in interactively. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PrintMotd Specifies whether sshd(8) should print /etc/motd when a user logs in interactively. (On some systems it is also printed by the shell, /etc/profile, or equivalent.) The default is M-bM-^@M-^\yesM-bM-^@M-^]. Protocol Specifies the protocol versions sshd(8) supports. The possible values are M-bM-^@M-^X1M-bM-^@M-^Y and M-bM-^@M-^X2M-bM-^@M-^Y. Multiple versions must be comma- separated. The default is M-bM-^@M-^X2M-bM-^@M-^Y. Protocol 1 suffers from a number of cryptographic weaknesses and should not be used. It is only offered to support legacy devices. Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. Specifying M-bM-^@M-^\2,1M-bM-^@M-^] is identical to M-bM-^@M-^\1,2M-bM-^@M-^]. PubkeyAcceptedKeyTypes Specifies the key types that will be accepted for public key authentication as a comma-separated pattern list. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa The -Q option of ssh(1) may be used to list supported key types. PubkeyAuthentication Specifies whether public key authentication is allowed. The default is M-bM-^@M-^\yesM-bM-^@M-^]. RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the TIME FORMATS section. The default value for RekeyLimit is M-bM-^@M-^\default noneM-bM-^@M-^], which means that rekeying is performed after the cipher's default amount of data has been sent or received and no time based rekeying is done. RevokedKeys Specifies revoked public keys file, or M-bM-^@M-^\noneM-bM-^@M-^] to not use one. Keys listed in this file will be refused for public key authentication. Note that if this file is not readable, then public key authentication will be refused for all users. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by ssh-keygen(1). For more information on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 1 only. RSAAuthentication Specifies whether pure RSA authentication is allowed. The default is M-bM-^@M-^\yesM-bM-^@M-^]. This option applies to protocol version 1 only. ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. The default and minimum value is 1024. StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. This option is only used for port forwarding to a Unix-domain socket file. The default value is 0177, which creates a Unix-domain socket file that is readable and writable only by the owner. Note that not all operating systems honor the file mode on Unix-domain socket files. StreamLocalBindUnlink Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new one. If the socket file already exists and StreamLocalBindUnlink is not enabled, sshd will be unable to forward the port to the Unix- domain socket file. This option is only used for port forwarding to a Unix-domain socket file. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. StrictModes Specifies whether sshd(8) should check file modes and ownership of the user's files and home directory before accepting login. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this does not apply to ChrootDirectory, whose permissions and ownership are checked unconditionally. Subsystem Configures an external subsystem (e.g. file transfer daemon). Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request. The command sftp-server(8) implements the M-bM-^@M-^\sftpM-bM-^@M-^] file transfer subsystem. Alternately the name M-bM-^@M-^\internal-sftpM-bM-^@M-^] implements an in-process M-bM-^@M-^\sftpM-bM-^@M-^] server. This may simplify configurations using ChrootDirectory to force a different filesystem root on clients. By default no subsystems are defined. SyslogFacility Gives the facility code that is used when logging messages from sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. TCPKeepAlive Specifies whether the system should send TCP keepalive messages to the other side. If they are sent, death of the connection or crash of one of the machines will be properly noticed. However, this means that connections will die if the route is down temporarily, and some people find it annoying. On the other hand, if TCP keepalives are not sent, sessions may hang indefinitely on the server, leaving M-bM-^@M-^\ghostM-bM-^@M-^] users and consuming server resources. The default is M-bM-^@M-^\yesM-bM-^@M-^] (to send TCP keepalive messages), and the server will notice if the network goes down or the client host crashes. This avoids infinitely hanging sessions. To disable TCP keepalive messages, the value should be set to M-bM-^@M-^\noM-bM-^@M-^]. TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or M-bM-^@M-^\noneM-bM-^@M-^] to not use one. Keys are listed one per line; empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are allowed. If a certificate is presented for authentication and has its signing CA key listed in this file, then it may be used for authentication for any user listed in the certificate's principals list. Note that certificates that lack a list of principals will not be permitted for authentication using TrustedUserCAKeys. For more details on certificates, see the CERTIFICATES section in ssh-keygen(1). UseDNS Specifies whether sshd(8) should look up the remote host name, and to check that the resolved host name for the remote IP address maps back to the very same IP address. If this option is set to M-bM-^@M-^\noM-bM-^@M-^] (the default) then only addresses and not host names may be used in ~/.ssh/known_hosts from and sshd_config Match Host directives. UseLogin Specifies whether login(1) is used for interactive login sessions. The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that login(1) is never used for remote command execution. Note also, that if this is enabled, X11Forwarding will be disabled because login(1) does not know how to handle xauth(1) cookies. If UsePrivilegeSeparation is specified, it will be disabled after authentication. UsePAM Enables the Pluggable Authentication Module interface. If set to M-bM-^@M-^\yesM-bM-^@M-^] this will enable PAM authentication using ChallengeResponseAuthentication and PasswordAuthentication in addition to PAM account and session module processing for all authentication types. Because PAM challenge-response authentication usually serves an equivalent role to password authentication, you should disable either PasswordAuthentication or ChallengeResponseAuthentication. If UsePAM is enabled, you will not be able to run sshd(8) as a non-root user. The default is M-bM-^@M-^\noM-bM-^@M-^]. UsePrivilegeSeparation Specifies whether sshd(8) separates privileges by creating an unprivileged child process to deal with incoming network traffic. After successful authentication, another process will be created that has the privilege of the authenticated user. The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\sandboxM-bM-^@M-^]. If UsePrivilegeSeparation is set to M-bM-^@M-^\sandboxM-bM-^@M-^] then the pre- authentication unprivileged process is subject to additional restrictions. The default is M-bM-^@M-^\sandboxM-bM-^@M-^]. VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is M-bM-^@M-^\noneM-bM-^@M-^]. X11DisplayOffset Specifies the first display number available for sshd(8)'s X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. When X11 forwarding is enabled, there may be additional exposure to the server and to client displays if the sshd(8) proxy display is configured to listen on the wildcard address (see X11UseLocalhost below), though this is not the default. Additionally, the authentication spoofing and authentication data verification and substitution occur on the client side. The security risk of using X11 forwarding is that the client's X11 display server may be exposed to attack when the SSH client requests forwarding (see the warnings for ForwardX11 in ssh_config(5)). A system administrator may have a stance in which they want to protect clients that may expose themselves to attack by unwittingly requesting X11 forwarding, which can warrant a M-bM-^@M-^\noM-bM-^@M-^] setting. Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own forwarders. X11 forwarding is automatically disabled if UseLogin is enabled. X11UseLocalhost Specifies whether sshd(8) should bind the X11 forwarding server to the loopback address or to the wildcard address. By default, sshd binds the forwarding server to the loopback address and sets the hostname part of the DISPLAY environment variable to M-bM-^@M-^\localhostM-bM-^@M-^]. This prevents remote hosts from connecting to the proxy display. However, some older X11 clients may not function with this configuration. X11UseLocalhost may be set to M-bM-^@M-^\noM-bM-^@M-^] to specify that the forwarding server should be bound to the wildcard address. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. XAuthLocation Specifies the full pathname of the xauth(1) program, or M-bM-^@M-^\noneM-bM-^@M-^] to not use one. The default is /usr/X11R6/bin/xauth. TIME FORMATS sshd(8) command-line arguments and configuration file options that specify time may be expressed using a sequence of the form: time[qualifier], where time is a positive integer value and qualifier is one of the following: M-bM-^_M-(noneM-bM-^_M-) seconds s | S seconds m | M minutes h | H hours d | D days w | W weeks Each member of the sequence is added together to calculate the total time value. Time format examples: 600 600 seconds (10 minutes) 10m 10 minutes 1h30m 1 hour 30 minutes (90 minutes) FILES /etc/ssh/sshd_config Contains configuration data for sshd(8). This file should be writable by root only, but it is recommended (though not necessary) that it be world-readable. SEE ALSO sshd(8) AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 openssh-7.2p2/ssh_config.0010064400017500001750000001701671267007033000136670ustar00djmdjmSSH_CONFIG(5) File Formats Manual SSH_CONFIG(5) NAME ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files SYNOPSIS ~/.ssh/config /etc/ssh/ssh_config DESCRIPTION ssh(1) obtains configuration data from the following sources in the following order: 1. command-line options 2. user's configuration file (~/.ssh/config) 3. system-wide configuration file (/etc/ssh/ssh_config) For each parameter, the first obtained value will be used. The configuration files contain sections separated by M-bM-^@M-^\HostM-bM-^@M-^] specifications, and that section is only applied for hosts that match one of the patterns given in the specification. The matched host name is usually the one given on the command line (see the CanonicalizeHostname option for exceptions.) Since the first obtained value for each parameter is used, more host- specific declarations should be given near the beginning of the file, and general defaults at the end. The configuration file has the following format: Empty lines and lines starting with M-bM-^@M-^X#M-bM-^@M-^Y are comments. Otherwise a line is of the format M-bM-^@M-^\keyword argumentsM-bM-^@M-^]. Configuration options may be separated by whitespace or optional whitespace and exactly one M-bM-^@M-^X=M-bM-^@M-^Y; the latter format is useful to avoid the need to quote whitespace when specifying configuration options using the ssh, scp, and sftp -o option. Arguments may optionally be enclosed in double quotes (") in order to represent arguments containing spaces. The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): Host Restricts the following declarations (up to the next Host or Match keyword) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is provided, they should be separated by whitespace. A single M-bM-^@M-^X*M-bM-^@M-^Y as a pattern can be used to provide global defaults for all hosts. The host is usually the hostname argument given on the command line (see the CanonicalizeHostname option for exceptions.) A pattern entry may be negated by prefixing it with an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). If a negated entry is matched, then the Host entry is ignored, regardless of whether any other patterns on the line match. Negated matches are therefore useful to provide exceptions for wildcard matches. See PATTERNS for more information on patterns. Match Restricts the following declarations (up to the next Host or Match keyword) to be used only when the conditions following the Match keyword are satisfied. Match conditions are specified using one or more criteria or the single token all which always matches. The available criteria keywords are: canonical, exec, host, originalhost, user, and localuser. The all criteria must appear alone or immediately after canonical. Other criteria may be combined arbitrarily. All criteria but all and canonical require an argument. Criteria may be negated by prepending an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). The canonical keyword matches only when the configuration file is being re-parsed after hostname canonicalization (see the CanonicalizeHostname option.) This may be useful to specify conditions that work with canonical host names only. The exec keyword executes the specified command under the user's shell. If the command returns a zero exit status then the condition is considered true. Commands containing whitespace characters must be quoted. The following character sequences in the command will be expanded prior to execution: M-bM-^@M-^X%LM-bM-^@M-^Y will be substituted by the first component of the local host name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted by the local host name (including any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted by the target host name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by the original target host name specified on the command-line, M-bM-^@M-^X%pM-bM-^@M-^Y the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by the remote login username, and M-bM-^@M-^X%uM-bM-^@M-^Y by the username of the user running ssh(1). The other keywords' criteria must be single entries or comma- separated lists and may use the wildcard and negation operators described in the PATTERNS section. The criteria for the host keyword are matched against the target hostname, after any substitution by the Hostname or CanonicalizeHostname options. The originalhost keyword matches against the hostname as it was specified on the command-line. The user keyword matches against the target username on the remote host. The localuser keyword matches against the name of the local user running ssh(1) (this keyword may be useful in system-wide ssh_config files). AddKeysToAgent Specifies whether keys should be automatically added to a running ssh-agent(1). If this option is set to M-bM-^@M-^\yesM-bM-^@M-^] and a key is loaded from a file, the key and its passphrase are added to the agent with the default lifetime, as if by ssh-add(1). If this option is set to M-bM-^@M-^\askM-bM-^@M-^], ssh will require confirmation using the SSH_ASKPASS program before adding a key (see ssh-add(1) for details). If this option is set to M-bM-^@M-^\confirmM-bM-^@M-^], each use of the key must be confirmed, as if the -c option was specified to ssh-add(1). If this option is set to M-bM-^@M-^\noM-bM-^@M-^], no keys are added to the agent. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\confirmM-bM-^@M-^], M-bM-^@M-^\askM-bM-^@M-^], or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. AddressFamily Specifies which address family to use when connecting. Valid arguments are M-bM-^@M-^\anyM-bM-^@M-^], M-bM-^@M-^\inetM-bM-^@M-^] (use IPv4 only), or M-bM-^@M-^\inet6M-bM-^@M-^] (use IPv6 only). The default is M-bM-^@M-^\anyM-bM-^@M-^]. BatchMode If set to M-bM-^@M-^\yesM-bM-^@M-^], passphrase/password querying will be disabled. This option is useful in scripts and other batch jobs where no user is present to supply the password. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. BindAddress Use the specified address on the local machine as the source address of the connection. Only useful on systems with more than one address. Note that this option does not work if UsePrivilegedPort is set to M-bM-^@M-^\yesM-bM-^@M-^]. CanonicalDomains When CanonicalizeHostname is enabled, this option specifies the list of domain suffixes in which to search for the specified destination host. CanonicalizeFallbackLocal Specifies whether to fail with an error when hostname canonicalization fails. The default, M-bM-^@M-^\yesM-bM-^@M-^], will attempt to look up the unqualified hostname using the system resolver's search rules. A value of M-bM-^@M-^\noM-bM-^@M-^] will cause ssh(1) to fail instantly if CanonicalizeHostname is enabled and the target hostname cannot be found in any of the domains specified by CanonicalDomains. CanonicalizeHostname Controls whether explicit hostname canonicalization is performed. The default, M-bM-^@M-^\noM-bM-^@M-^], is not to perform any name rewriting and let the system resolver handle all hostname lookups. If set to M-bM-^@M-^\yesM-bM-^@M-^] then, for connections that do not use a ProxyCommand, ssh(1) will attempt to canonicalize the hostname specified on the command line using the CanonicalDomains suffixes and CanonicalizePermittedCNAMEs rules. If CanonicalizeHostname is set to M-bM-^@M-^\alwaysM-bM-^@M-^], then canonicalization is applied to proxied connections too. If this option is enabled, then the configuration files are processed again using the new target name to pick up any new configuration in matching Host and Match stanzas. CanonicalizeMaxDots Specifies the maximum number of dot characters in a hostname before canonicalization is disabled. The default, M-bM-^@M-^\1M-bM-^@M-^], allows a single dot (i.e. hostname.subdomain). CanonicalizePermittedCNAMEs Specifies rules to determine whether CNAMEs should be followed when canonicalizing hostnames. The rules consist of one or more arguments of source_domain_list:target_domain_list, where source_domain_list is a pattern-list of domains that may follow CNAMEs in canonicalization, and target_domain_list is a pattern- list of domains that they may resolve to. For example, M-bM-^@M-^\*.a.example.com:*.b.example.com,*.c.example.comM-bM-^@M-^] will allow hostnames matching M-bM-^@M-^\*.a.example.comM-bM-^@M-^] to be canonicalized to names in the M-bM-^@M-^\*.b.example.comM-bM-^@M-^] or M-bM-^@M-^\*.c.example.comM-bM-^@M-^] domains. CertificateFile Specifies a file from which the user's certificate is read. A corresponding private key must be provided separately in order to use this certificate either from an IdentityFile directive or -i flag to ssh(1), via ssh-agent(1), or via a PKCS11Provider. The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: M-bM-^@M-^X%dM-bM-^@M-^Y (local user's home directory), M-bM-^@M-^X%uM-bM-^@M-^Y (local user name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host name), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host name) or M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name). It is possible to have multiple certificate files specified in configuration files; these certificates will be tried in sequence. Multiple CertificateFile directives will add to the list of certificates used for authentication. ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. CheckHostIP If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will additionally check the host IP address in the known_hosts file. This allows ssh to detect if a host key changed due to DNS spoofing and will add addresses of destination hosts to ~/.ssh/known_hosts in the process, regardless of the setting of StrictHostKeyChecking. If the option is set to M-bM-^@M-^\noM-bM-^@M-^], the check will not be executed. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Cipher Specifies the cipher to use for encrypting the session in protocol version 1. Currently, M-bM-^@M-^\blowfishM-bM-^@M-^], M-bM-^@M-^\3desM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^] are supported. des is only supported in the ssh(1) client for interoperability with legacy protocol 1 implementations that do not support the 3des cipher. Its use is strongly discouraged due to cryptographic weaknesses. The default is M-bM-^@M-^\3desM-bM-^@M-^]. Ciphers Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified ciphers will be appended to the default set instead of replacing them. The supported ciphers are: 3des-cbc aes128-cbc aes192-cbc aes256-cbc aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com arcfour arcfour128 arcfour256 blowfish-cbc cast128-cbc chacha20-poly1305@openssh.com The default is: chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com, aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc The list of available ciphers may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be cleared. This option is primarily useful when used from the ssh(1) command line to clear port forwardings set in configuration files, and is automatically set by scp(1) and sftp(1). The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. Compression Specifies whether to use compression. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. CompressionLevel Specifies the compression level to use if compression is enabled. The argument must be an integer from 1 (fast) to 9 (slow, best). The default level is 6, which is good for most applications. The meaning of the values is the same as in gzip(1). Note that this option applies to protocol version 1 only. ConnectionAttempts Specifies the number of tries (one per second) to make before exiting. The argument must be an integer. This may be useful in scripts if the connection sometimes fails. The default is 1. ConnectTimeout Specifies the timeout (in seconds) used when connecting to the SSH server, instead of using the default system TCP timeout. This value is used only when the target is down or really unreachable, not when it refuses the connection. ControlMaster Enables the sharing of multiple sessions over a single network connection. When set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will listen for connections on a control socket specified using the ControlPath argument. Additional sessions can connect to this socket using the same ControlPath with ControlMaster set to M-bM-^@M-^\noM-bM-^@M-^] (the default). These sessions will try to reuse the master instance's network connection rather than initiating new ones, but will fall back to connecting normally if the control socket does not exist, or is not listening. Setting this to M-bM-^@M-^\askM-bM-^@M-^] will cause ssh to listen for control connections, but require confirmation using ssh-askpass(1). If the ControlPath cannot be opened, ssh will continue without connecting to a master instance. X11 and ssh-agent(1) forwarding is supported over these multiplexed connections, however the display and agent forwarded will be the one belonging to the master connection i.e. it is not possible to forward multiple displays or agents. Two additional options allow for opportunistic multiplexing: try to use a master connection but fall back to creating a new one if one does not already exist. These options are: M-bM-^@M-^\autoM-bM-^@M-^] and M-bM-^@M-^\autoaskM-bM-^@M-^]. The latter requires confirmation like the M-bM-^@M-^\askM-bM-^@M-^] option. ControlPath Specify the path to the control socket used for connection sharing as described in the ControlMaster section above or the string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. In the path, M-bM-^@M-^X%LM-bM-^@M-^Y will be substituted by the first component of the local host name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted by the local host name (including any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted by the target host name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by the original target host name specified on the command line, M-bM-^@M-^X%pM-bM-^@M-^Y the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by the remote login username, M-bM-^@M-^X%uM-bM-^@M-^Y by the username and M-bM-^@M-^X%iM-bM-^@M-^Y by the numeric user ID (uid) of the user running ssh(1), and M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: %l%h%p%r. It is recommended that any ControlPath used for opportunistic connection sharing include at least %h, %p, and %r (or alternatively %C) and be placed in a directory that is not writable by other users. This ensures that shared connections are uniquely identified. ControlPersist When used in conjunction with ControlMaster, specifies that the master connection should remain open in the background (waiting for future client connections) after the initial client connection has been closed. If set to M-bM-^@M-^\noM-bM-^@M-^], then the master connection will not be placed into the background, and will close as soon as the initial client connection is closed. If set to M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\0M-bM-^@M-^], then the master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the ssh(1) M-bM-^@M-^\-O exitM-bM-^@M-^] option). If set to a time in seconds, or a time in any of the formats documented in sshd_config(5), then the backgrounded master connection will automatically terminate after it has remained idle (with no client connections) for the specified time. DynamicForward Specifies that a TCP port on the local machine be forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. The argument must be [bind_address:]port. IPv6 addresses can be specified by enclosing addresses in square brackets. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh(1) will act as a SOCKS server. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. EnableSSHKeysign Setting this option to M-bM-^@M-^\yesM-bM-^@M-^] in the global client configuration file /etc/ssh/ssh_config enables the use of the helper program ssh-keysign(8) during HostbasedAuthentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. This option should be placed in the non-hostspecific section. See ssh-keysign(8) for more information. EscapeChar Sets the escape character (default: M-bM-^@M-^X~M-bM-^@M-^Y). The escape character can also be set on the command line. The argument should be a single character, M-bM-^@M-^X^M-bM-^@M-^Y followed by a letter, or M-bM-^@M-^\noneM-bM-^@M-^] to disable the escape character entirely (making the connection transparent for binary data). ExitOnForwardFailure Specifies whether ssh(1) should terminate the connection if it cannot set up all requested dynamic, tunnel, local, and remote port forwardings, (e.g. if either end is unable to bind and listen on a specified port). Note that ExitOnForwardFailure does not apply to connections made over port forwardings and will not, for example, cause ssh(1) to exit if TCP connections to the ultimate forwarding destination fail. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's Unix-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. ForwardX11 Specifies whether X11 connections will be automatically redirected over the secure channel and DISPLAY set. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. X11 forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the user's X11 authorization database) can access the local X11 display through the forwarded connection. An attacker may then be able to perform activities such as keystroke monitoring if the ForwardX11Trusted option is also enabled. ForwardX11Timeout Specify a timeout for untrusted X11 forwarding using the format described in the TIME FORMATS section of sshd_config(5). X11 connections received by ssh(1) after this time will be refused. The default is to disable untrusted X11 forwarding after twenty minutes has elapsed. ForwardX11Trusted If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], remote X11 clients will have full access to the original X11 display. If this option is set to M-bM-^@M-^\noM-bM-^@M-^], remote X11 clients will be considered untrusted and prevented from stealing or tampering with data belonging to trusted X11 clients. Furthermore, the xauth(1) token used for the session will be set to expire after 20 minutes. Remote clients will be refused access after this time. The default is M-bM-^@M-^\noM-bM-^@M-^]. See the X11 SECURITY extension specification for full details on the restrictions imposed on untrusted clients. GatewayPorts Specifies whether remote hosts are allowed to connect to local forwarded ports. By default, ssh(1) binds local port forwardings to the loopback address. This prevents other remote hosts from connecting to forwarded ports. GatewayPorts can be used to specify that ssh should bind local port forwardings to the wildcard address, thus allowing remote hosts to connect to forwarded ports. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. GlobalKnownHostsFile Specifies one or more files to use for the global host key database, separated by whitespace. The default is /etc/ssh/ssh_known_hosts, /etc/ssh/ssh_known_hosts2. GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is M-bM-^@M-^\noM-bM-^@M-^]. HashKnownHosts Indicates that ssh(1) should hash host names and addresses when they are added to ~/.ssh/known_hosts. These hashed names may be used normally by ssh(1) and sshd(8), but they do not reveal identifying information should the file's contents be disclosed. The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that existing names and addresses in known hosts files will not be converted automatically, but may be manually hashed using ssh-keygen(1). HostbasedAuthentication Specifies whether to try rhosts based authentication with public key authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. HostbasedKeyTypes Specifies the key types that will be used for hostbased authentication as a comma-separated pattern list. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa The -Q option of ssh(1) may be used to list supported key types. HostKeyAlgorithms Specifies the host key algorithms that the client wants to use in order of preference. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be appended to the default set instead of replacing them. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa If hostkeys are known for the destination host then this default is modified to prefer their algorithms. The list of available key types may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\keyM-bM-^@M-^]. HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key in the host key database files. This option is useful for tunneling SSH connections or for multiple servers running on a single host. HostName Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts. If the hostname contains the character sequence M-bM-^@M-^X%hM-bM-^@M-^Y, then this will be replaced with the host name specified on the command line (this is useful for manipulating unqualified names). The character sequence M-bM-^@M-^X%%M-bM-^@M-^Y will be replaced by a single M-bM-^@M-^X%M-bM-^@M-^Y character, which may be used when specifying IPv6 link-local addresses. The default is the name given on the command line. Numeric IP addresses are also permitted (both on the command line and in HostName specifications). IdentitiesOnly Specifies that ssh(1) should only use the authentication identity and certificate files explicitly configured in the ssh_config files or passed on the ssh(1) command-line, even if ssh-agent(1) or a PKCS11Provider offers more identities. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. This option is intended for situations where ssh-agent offers many different identities. The default is M-bM-^@M-^\noM-bM-^@M-^]. IdentityFile Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication identity is read. The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication unless IdentitiesOnly is set. If no certificates have been explicitly specified by CertificateFile, ssh(1) will try to load certificate information from the filename obtained by appending -cert.pub to the path of a specified IdentityFile. The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: M-bM-^@M-^X%dM-bM-^@M-^Y (local user's home directory), M-bM-^@M-^X%uM-bM-^@M-^Y (local user name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host name), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host name) or M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name). It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence. Multiple IdentityFile directives will add to the list of identities tried (this behaviour differs from that of other configuration directives). IdentityFile may be used in conjunction with IdentitiesOnly to select which identities in an agent are offered during authentication. IdentityFile may also be used in conjunction with CertificateFile in order to provide any certificate also needed for authentication with the identity. IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. This may be used to suppress errors if ssh_config contains options that are unrecognised by ssh(1). It is recommended that IgnoreUnknown be listed early in the configuration file as it will not be applied to unknown options that appear before it. IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. Accepted values are M-bM-^@M-^\af11M-bM-^@M-^], M-bM-^@M-^\af12M-bM-^@M-^], M-bM-^@M-^\af13M-bM-^@M-^], M-bM-^@M-^\af21M-bM-^@M-^], M-bM-^@M-^\af22M-bM-^@M-^], M-bM-^@M-^\af23M-bM-^@M-^], M-bM-^@M-^\af31M-bM-^@M-^], M-bM-^@M-^\af32M-bM-^@M-^], M-bM-^@M-^\af33M-bM-^@M-^], M-bM-^@M-^\af41M-bM-^@M-^], M-bM-^@M-^\af42M-bM-^@M-^], M-bM-^@M-^\af43M-bM-^@M-^], M-bM-^@M-^\cs0M-bM-^@M-^], M-bM-^@M-^\cs1M-bM-^@M-^], M-bM-^@M-^\cs2M-bM-^@M-^], M-bM-^@M-^\cs3M-bM-^@M-^], M-bM-^@M-^\cs4M-bM-^@M-^], M-bM-^@M-^\cs5M-bM-^@M-^], M-bM-^@M-^\cs6M-bM-^@M-^], M-bM-^@M-^\cs7M-bM-^@M-^], M-bM-^@M-^\efM-bM-^@M-^], M-bM-^@M-^\lowdelayM-bM-^@M-^], M-bM-^@M-^\throughputM-bM-^@M-^], M-bM-^@M-^\reliabilityM-bM-^@M-^], or a numeric value. This option may take one or two arguments, separated by whitespace. If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is M-bM-^@M-^\lowdelayM-bM-^@M-^] for interactive sessions and M-bM-^@M-^\throughputM-bM-^@M-^] for non-interactive sessions. KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. KbdInteractiveDevices Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. The default is to use the server specified list. The methods available vary depending on what the server supports. For an OpenSSH server, it may be zero or more of: M-bM-^@M-^\bsdauthM-bM-^@M-^], M-bM-^@M-^\pamM-bM-^@M-^], and M-bM-^@M-^\skeyM-bM-^@M-^]. KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified methods will be appended to the default set instead of replacing them. The default is: curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1 The list of available key exchange algorithms may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\kexM-bM-^@M-^]. LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. The command string extends to the end of the line, and is executed with the user's shell. The following escape character substitutions will be performed: M-bM-^@M-^X%dM-bM-^@M-^Y (local user's home directory), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host name), M-bM-^@M-^X%nM-bM-^@M-^Y (host name as provided on the command line), M-bM-^@M-^X%pM-bM-^@M-^Y (remote port), M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name) or M-bM-^@M-^X%uM-bM-^@M-^Y (local user name) or M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: %l%h%p%r. The command is run synchronously and does not have access to the session of the ssh(1) that spawned it. It should not be used for interactive commands. This directive is ignored unless PermitLocalCommand has been enabled. LocalForward Specifies that a TCP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. The first argument must be [bind_address:]port and the second argument must be host:hostport. IPv6 addresses can be specified by enclosing addresses in square brackets. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. LogLevel Gives the verbosity level that is used when logging messages from ssh(1). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of verbose output. MACs Specifies the MAC (message authentication code) algorithms in order of preference. The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma- separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified algorithms will be appended to the default set instead of replacing them. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. The default is: umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512,hmac-sha1 The list of available MAC algorithms may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\macM-bM-^@M-^]. NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of the machines and the user will get many warnings about changed host keys. However, this option disables host authentication for localhost. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is to check the host key for localhost. NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. The default is 3. PasswordAuthentication Specifies whether to use password authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PermitLocalCommand Allow local command execution via the LocalCommand option or using the !command escape sequence in ssh(1). The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. PKCS11Provider Specifies which PKCS#11 provider to use. The argument to this keyword is the PKCS#11 shared library ssh(1) should use to communicate with a PKCS#11 token providing the user's private RSA key. Port Specifies the port number to connect on the remote host. The default is 22. PreferredAuthentications Specifies the order in which the client should try authentication methods. This allows a client to prefer one method (e.g. keyboard-interactive) over another method (e.g. password). The default is: gssapi-with-mic,hostbased,publickey, keyboard-interactive,password Protocol Specifies the protocol versions ssh(1) should support in order of preference. The possible values are M-bM-^@M-^X1M-bM-^@M-^Y and M-bM-^@M-^X2M-bM-^@M-^Y. Multiple versions must be comma-separated. When this option is set to M-bM-^@M-^\2,1M-bM-^@M-^] ssh will try version 2 and fall back to version 1 if version 2 is not available. The default is M-bM-^@M-^X2M-bM-^@M-^Y. Protocol 1 suffers from a number of cryptographic weaknesses and should not be used. It is only offered to support legacy devices. ProxyCommand Specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed using the user's shell M-bM-^@M-^XexecM-bM-^@M-^Y directive to avoid a lingering shell process. In the command string, any occurrence of M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted by the host name to connect, M-bM-^@M-^X%pM-bM-^@M-^Y by the port, and M-bM-^@M-^X%rM-bM-^@M-^Y by the remote user name. The command can be basically anything, and should read from its standard input and write to its standard output. It should eventually connect an sshd(8) server running on some machine, or execute sshd -i somewhere. Host key management will be done using the HostName of the host being connected (defaulting to the name typed by the user). Setting the command to M-bM-^@M-^\noneM-bM-^@M-^] disables this option entirely. Note that CheckHostIP is not available for connects with a proxy command. This directive is useful in conjunction with nc(1) and its proxy support. For example, the following directive would connect via an HTTP proxy at 192.0.2.0: ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p ProxyUseFdpass Specifies that ProxyCommand will pass a connected file descriptor back to ssh(1) instead of continuing to execute and pass data. The default is M-bM-^@M-^\noM-bM-^@M-^]. PubkeyAcceptedKeyTypes Specifies the key types that will be used for public key authentication as a comma-separated pattern list. Alternately if the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the key types after it will be appended to the default instead of replacing it. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-ed25519-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-ed25519,ssh-rsa The -Q option of ssh(1) may be used to list supported key types. PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the TIME FORMATS section of sshd_config(5). The default value for RekeyLimit is M-bM-^@M-^\default noneM-bM-^@M-^], which means that rekeying is performed after the cipher's default amount of data has been sent or received and no time based rekeying is done. RemoteForward Specifies that a TCP port on the remote machine be forwarded over the secure channel to the specified host and port from the local machine. The first argument must be [bind_address:]port and the second argument must be host:hostport. IPv6 addresses can be specified by enclosing addresses in square brackets. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Privileged ports can be forwarded only when logging in as root on the remote machine. If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically allocated on the server and reported to the client at run time. If the bind_address is not specified, the default is to only bind to loopback addresses. If the bind_address is M-bM-^@M-^X*M-bM-^@M-^Y or an empty string, then the forwarding is requested to listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)). RequestTTY Specifies whether to request a pseudo-tty for the session. The argument may be one of: M-bM-^@M-^\noM-bM-^@M-^] (never request a TTY), M-bM-^@M-^\yesM-bM-^@M-^] (always request a TTY when standard input is a TTY), M-bM-^@M-^\forceM-bM-^@M-^] (always request a TTY) or M-bM-^@M-^\autoM-bM-^@M-^] (request a TTY when opening a login session). This option mirrors the -t and -T flags for ssh(1). RevokedHostKeys Specifies revoked host public keys. Keys listed in this file will be refused for host authentication. Note that if this file does not exist or is not readable, then host authentication will be refused for all hosts. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by ssh-keygen(1). For more information on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 1 only and requires ssh(1) to be setuid root. RSAAuthentication Specifies whether to try RSA authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. RSA authentication will only be attempted if the identity file exists, or an authentication agent is running. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option applies to protocol version 1 only. SendEnv Specifies what variables from the local environ(7) should be sent to the server. The server must also support it, and the server must be configured to accept these environment variables. Note that the TERM environment variable is always sent whenever a pseudo-terminal is requested as it is required by the protocol. Refer to AcceptEnv in sshd_config(5) for how to configure the server. Variables are specified by name, which may contain wildcard characters. Multiple environment variables may be separated by whitespace or spread across multiple SendEnv directives. The default is not to send any environment variables. See PATTERNS for more information on patterns. ServerAliveCountMax Sets the number of server alive messages (see below) which may be sent without ssh(1) receiving any messages back from the server. If this threshold is reached while server alive messages are being sent, ssh will disconnect from the server, terminating the session. It is important to note that the use of server alive messages is very different from TCPKeepAlive (below). The server alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by TCPKeepAlive is spoofable. The server alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive. The default value is 3. If, for example, ServerAliveInterval (see below) is set to 15 and ServerAliveCountMax is left at the default, if the server becomes unresponsive, ssh will disconnect after approximately 45 seconds. ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. This option is only used for port forwarding to a Unix-domain socket file. The default value is 0177, which creates a Unix-domain socket file that is readable and writable only by the owner. Note that not all operating systems honor the file mode on Unix-domain socket files. StreamLocalBindUnlink Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new one. If the socket file already exists and StreamLocalBindUnlink is not enabled, ssh will be unable to forward the port to the Unix- domain socket file. This option is only used for port forwarding to a Unix-domain socket file. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. StrictHostKeyChecking If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will never automatically add host keys to the ~/.ssh/known_hosts file, and refuses to connect to hosts whose host key has changed. This provides maximum protection against trojan horse attacks, though it can be annoying when the /etc/ssh/ssh_known_hosts file is poorly maintained or when connections to new hosts are frequently made. This option forces the user to manually add all new hosts. If this flag is set to M-bM-^@M-^\noM-bM-^@M-^], ssh will automatically add new host keys to the user known hosts files. If this flag is set to M-bM-^@M-^\askM-bM-^@M-^], new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and ssh will refuse to connect to hosts whose host key has changed. The host keys of known hosts will be verified automatically in all cases. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\askM-bM-^@M-^]. The default is M-bM-^@M-^\askM-bM-^@M-^]. TCPKeepAlive Specifies whether the system should send TCP keepalive messages to the other side. If they are sent, death of the connection or crash of one of the machines will be properly noticed. However, this means that connections will die if the route is down temporarily, and some people find it annoying. The default is M-bM-^@M-^\yesM-bM-^@M-^] (to send TCP keepalive messages), and the client will notice if the network goes down or the remote host dies. This is important in scripts, and many users want it too. To disable TCP keepalive messages, the value should be set to M-bM-^@M-^\noM-bM-^@M-^]. Tunnel Request tun(4) device forwarding between the client and the server. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\point-to-pointM-bM-^@M-^] (layer 3), M-bM-^@M-^\ethernetM-bM-^@M-^] (layer 2), or M-bM-^@M-^\noM-bM-^@M-^]. Specifying M-bM-^@M-^\yesM-bM-^@M-^] requests the default tunnel mode, which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. TunnelDevice Specifies the tun(4) devices to open on the client (local_tun) and the server (remote_tun). The argument must be local_tun[:remote_tun]. The devices may be specified by numerical ID or the keyword M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device. If remote_tun is not specified, it defaults to M-bM-^@M-^\anyM-bM-^@M-^]. The default is M-bM-^@M-^\any:anyM-bM-^@M-^]. UpdateHostKeys Specifies whether ssh(1) should accept notifications of additional hostkeys from the server sent after authentication has completed and add them to UserKnownHostsFile. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^] (the default) or M-bM-^@M-^\askM-bM-^@M-^]. Enabling this option allows learning alternate hostkeys for a server and supports graceful key rotation by allowing a server to send replacement public keys before old ones are removed. Additional hostkeys are only accepted if the key used to authenticate the host was already trusted or explicitly accepted by the user. If UpdateHostKeys is set to M-bM-^@M-^\askM-bM-^@M-^], then the user is asked to confirm the modifications to the known_hosts file. Confirmation is currently incompatible with ControlPersist, and will be disabled if it is enabled. Presently, only sshd(8) from OpenSSH 6.8 and greater support the M-bM-^@M-^\hostkeys@openssh.comM-bM-^@M-^] protocol extension used to inform the client of all the server's hostkeys. UsePrivilegedPort Specifies whether to use a privileged port for outgoing connections. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. If set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) must be setuid root. Note that this option must be set to M-bM-^@M-^\yesM-bM-^@M-^] for RhostsRSAAuthentication with older servers. User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line. UserKnownHostsFile Specifies one or more files to use for the user host key database, separated by whitespace. The default is ~/.ssh/known_hosts, ~/.ssh/known_hosts2. VerifyHostKeyDNS Specifies whether to verify the remote key using DNS and SSHFP resource records. If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], the client will implicitly trust keys that match a secure fingerprint from DNS. Insecure fingerprints will be handled as if this option was set to M-bM-^@M-^\askM-bM-^@M-^]. If this option is set to M-bM-^@M-^\askM-bM-^@M-^], information on fingerprint match will be displayed, but the user will still need to confirm new host keys according to the StrictHostKeyChecking option. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\askM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. See also VERIFYING HOST KEYS in ssh(1). VisualHostKey If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], an ASCII art representation of the remote host key fingerprint is printed in addition to the fingerprint string at login and for unknown host keys. If this flag is set to M-bM-^@M-^\noM-bM-^@M-^], no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. The default is M-bM-^@M-^\noM-bM-^@M-^]. XAuthLocation Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. PATTERNS A pattern consists of zero or more non-whitespace characters, M-bM-^@M-^X*M-bM-^@M-^Y (a wildcard that matches zero or more characters), or M-bM-^@M-^X?M-bM-^@M-^Y (a wildcard that matches exactly one character). For example, to specify a set of declarations for any host in the M-bM-^@M-^\.co.ukM-bM-^@M-^] set of domains, the following pattern could be used: Host *.co.uk The following pattern would match any host in the 192.168.0.[0-9] network range: Host 192.168.0.? A pattern-list is a comma-separated list of patterns. Patterns within pattern-lists may be negated by preceding them with an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). For example, to allow a key to be used from anywhere within an organization except from the M-bM-^@M-^\dialupM-bM-^@M-^] pool, the following entry (in authorized_keys) could be used: from="!*.dialup.example.com,*.example.com" FILES ~/.ssh/config This is the per-user configuration file. The format of this file is described above. This file is used by the SSH client. Because of the potential for abuse, this file must have strict permissions: read/write for the user, and not accessible by others. /etc/ssh/ssh_config Systemwide configuration file. This file provides defaults for those values that are not specified in the user's configuration file, and for those users who do not have a configuration file. This file must be world-readable. SEE ALSO ssh(1) AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. OpenBSD 5.9 February 20, 2016 OpenBSD 5.9 openssh-7.2p2/configure010075500017500001750000035650021267007037100133770ustar00djmdjm#! /bin/sh # From configure.ac Revision: 1.583 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for OpenSSH Portable. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='OpenSSH' PACKAGE_TARNAME='openssh' PACKAGE_VERSION='Portable' PACKAGE_STRING='OpenSSH Portable' PACKAGE_BUGREPORT='openssh-unix-dev@mindrot.org' ac_unique_file="ssh.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CPP GREP EGREP AWK RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR ac_ct_AR CAT KILL PERL SED ENT TEST_MINUS_S_SH SH GROFF NROFF MANDOC TEST_SHELL MANFMT PATH_GROUPADD_PROG PATH_USERADD_PROG MAKE_PACKAGE_SUPPORTED STARTUP_SCRIPT_SHELL LOGIN_PROGRAM_FALLBACK PATH_PASSWD_PROG LD PKGCONFIG LIBEDIT TEST_SSH_ECC COMMENT_OUT_ECC SSH_PRIVSEP_USER SSHLIBS SSHDLIBS KRB5CONF GSSLIBS K5LIBS PRIVSEP_PATH xauth_path STRIP_OPT XAUTH_PATH MANTYPE mansubdir user_path piddir TEST_SSH_IPV6 TEST_MALLOC_OPTIONS UNSUPPORTED_ALGORITHMS LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures OpenSSH Portable to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/openssh] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of OpenSSH Portable:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files --disable-strip Disable calling strip(1) on install --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-lastlog disable use of lastlog even if detected no --disable-utmp disable use of utmp even if detected no --disable-utmpx disable use of utmpx even if detected no --disable-wtmp disable use of wtmp even if detected no --disable-wtmpx disable use of wtmpx even if detected no --disable-libutil disable use of libutil (login() etc.) no --disable-pututline disable use of pututline() etc. (uwtmp) no --disable-pututxline disable use of pututxline() etc. (uwtmpx) no Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** --with-ssh1 Enable support for SSH protocol 1 --without-stackprotect Don't use compiler's stack protection --without-hardening Don't use toolchain hardening flags --without-rpath Disable auto-added -R linker paths --with-cflags Specify additional flags to pass to compiler --with-cppflags Specify additional flags to pass to preprocessor --with-ldflags Specify additional flags to pass to linker --with-libs Specify additional libraries to link with --with-Werror Build main code with -Werror --with-solaris-contracts Enable Solaris process contracts (experimental) --with-solaris-projects Enable Solaris projects (experimental) --with-solaris-privs Enable Solaris/Illumos privileges (experimental) --with-osfsia Enable Digital Unix SIA --with-zlib=PATH Use zlib in PATH --without-zlib-version-check Disable zlib version check --with-skey[=PATH] Enable S/Key support (optionally in PATH) --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp --with-audit=module Enable audit support (modules=debug,bsm,linux) --with-pie Build Position Independent Executables if possible --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support --with-prngd-port=PORT read entropy from PRNGD/EGD TCP localhost:PORT --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool) --with-pam Enable PAM support --with-privsep-user=user Specify non-privileged user for privilege separation --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) --with-xauth=PATH Specify path to xauth program --with-maildir=/path/to/mail Specify your system mail directory --with-mantype=man|cat|doc Set man page type --with-md5-passwords Enable use of MD5 passwords --without-shadow Disable shadow password support --with-ipaddr-display Use ip address instead of hostname in $DISPLAY --with-default-path= Specify default $PATH environment for server --with-superuser-path= Specify different path for super-user --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses --with-bsd-auth Enable BSD auth support --with-pid-dir=PATH Specify location of ssh.pid file --with-lastlog=FILE|DIR specify lastlog location common locations Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenSSH configure Portable generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenSSH $as_me Portable, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac # Checks for programs. for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 echo "${ECHO_T}$ac_ct_AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi # Extract the first word of "cat", so it can be a program name with args. set dummy cat; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_CAT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $CAT in [\\/]* | ?:[\\/]*) ac_cv_path_CAT="$CAT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CAT=$ac_cv_path_CAT if test -n "$CAT"; then { echo "$as_me:$LINENO: result: $CAT" >&5 echo "${ECHO_T}$CAT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "kill", so it can be a program name with args. set dummy kill; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_KILL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $KILL in [\\/]* | ?:[\\/]*) ac_cv_path_KILL="$KILL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_KILL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi KILL=$ac_cv_path_KILL if test -n "$KILL"; then { echo "$as_me:$LINENO: result: $KILL" >&5 echo "${ECHO_T}$KILL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi for ac_prog in perl5 perl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PERL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { echo "$as_me:$LINENO: result: $PERL" >&5 echo "${ECHO_T}$PERL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$PERL" && break done # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "ent", so it can be a program name with args. set dummy ent; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_ENT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $ENT in [\\/]* | ?:[\\/]*) ac_cv_path_ENT="$ENT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ENT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ENT=$ac_cv_path_ENT if test -n "$ENT"; then { echo "$as_me:$LINENO: result: $ENT" >&5 echo "${ECHO_T}$ENT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "bash", so it can be a program name with args. set dummy bash; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_TEST_MINUS_S_SH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $TEST_MINUS_S_SH in [\\/]* | ?:[\\/]*) ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TEST_MINUS_S_SH=$ac_cv_path_TEST_MINUS_S_SH if test -n "$TEST_MINUS_S_SH"; then { echo "$as_me:$LINENO: result: $TEST_MINUS_S_SH" >&5 echo "${ECHO_T}$TEST_MINUS_S_SH" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "ksh", so it can be a program name with args. set dummy ksh; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_TEST_MINUS_S_SH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $TEST_MINUS_S_SH in [\\/]* | ?:[\\/]*) ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TEST_MINUS_S_SH=$ac_cv_path_TEST_MINUS_S_SH if test -n "$TEST_MINUS_S_SH"; then { echo "$as_me:$LINENO: result: $TEST_MINUS_S_SH" >&5 echo "${ECHO_T}$TEST_MINUS_S_SH" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "sh", so it can be a program name with args. set dummy sh; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_TEST_MINUS_S_SH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $TEST_MINUS_S_SH in [\\/]* | ?:[\\/]*) ac_cv_path_TEST_MINUS_S_SH="$TEST_MINUS_S_SH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TEST_MINUS_S_SH=$ac_cv_path_TEST_MINUS_S_SH if test -n "$TEST_MINUS_S_SH"; then { echo "$as_me:$LINENO: result: $TEST_MINUS_S_SH" >&5 echo "${ECHO_T}$TEST_MINUS_S_SH" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "sh", so it can be a program name with args. set dummy sh; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_SH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $SH in [\\/]* | ?:[\\/]*) ac_cv_path_SH="$SH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SH=$ac_cv_path_SH if test -n "$SH"; then { echo "$as_me:$LINENO: result: $SH" >&5 echo "${ECHO_T}$SH" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "groff", so it can be a program name with args. set dummy groff; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_GROFF+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $GROFF in [\\/]* | ?:[\\/]*) ac_cv_path_GROFF="$GROFF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GROFF=$ac_cv_path_GROFF if test -n "$GROFF"; then { echo "$as_me:$LINENO: result: $GROFF" >&5 echo "${ECHO_T}$GROFF" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "nroff", so it can be a program name with args. set dummy nroff; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_NROFF+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $NROFF in [\\/]* | ?:[\\/]*) ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi NROFF=$ac_cv_path_NROFF if test -n "$NROFF"; then { echo "$as_me:$LINENO: result: $NROFF" >&5 echo "${ECHO_T}$NROFF" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "mandoc", so it can be a program name with args. set dummy mandoc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_MANDOC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MANDOC in [\\/]* | ?:[\\/]*) ac_cv_path_MANDOC="$MANDOC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MANDOC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MANDOC=$ac_cv_path_MANDOC if test -n "$MANDOC"; then { echo "$as_me:$LINENO: result: $MANDOC" >&5 echo "${ECHO_T}$MANDOC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi TEST_SHELL=sh if test "x$MANDOC" != "x" ; then MANFMT="$MANDOC" elif test "x$NROFF" != "x" ; then MANFMT="$NROFF -mandoc" elif test "x$GROFF" != "x" ; then MANFMT="$GROFF -mandoc -Tascii" else { echo "$as_me:$LINENO: WARNING: no manpage formatted found" >&5 echo "$as_me: WARNING: no manpage formatted found" >&2;} MANFMT="false" fi # Extract the first word of "groupadd", so it can be a program name with args. set dummy groupadd; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PATH_GROUPADD_PROG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PATH_GROUPADD_PROG in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_GROUPADD_PROG="$PATH_GROUPADD_PROG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/sbin${PATH_SEPARATOR}/etc do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PATH_GROUPADD_PROG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_GROUPADD_PROG" && ac_cv_path_PATH_GROUPADD_PROG="groupadd" ;; esac fi PATH_GROUPADD_PROG=$ac_cv_path_PATH_GROUPADD_PROG if test -n "$PATH_GROUPADD_PROG"; then { echo "$as_me:$LINENO: result: $PATH_GROUPADD_PROG" >&5 echo "${ECHO_T}$PATH_GROUPADD_PROG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "useradd", so it can be a program name with args. set dummy useradd; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PATH_USERADD_PROG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PATH_USERADD_PROG in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_USERADD_PROG="$PATH_USERADD_PROG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/sbin${PATH_SEPARATOR}/etc do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PATH_USERADD_PROG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PATH_USERADD_PROG" && ac_cv_path_PATH_USERADD_PROG="useradd" ;; esac fi PATH_USERADD_PROG=$ac_cv_path_PATH_USERADD_PROG if test -n "$PATH_USERADD_PROG"; then { echo "$as_me:$LINENO: result: $PATH_USERADD_PROG" >&5 echo "${ECHO_T}$PATH_USERADD_PROG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "pkgmk", so it can be a program name with args. set dummy pkgmk; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_MAKE_PACKAGE_SUPPORTED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$MAKE_PACKAGE_SUPPORTED"; then ac_cv_prog_MAKE_PACKAGE_SUPPORTED="$MAKE_PACKAGE_SUPPORTED" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MAKE_PACKAGE_SUPPORTED="yes" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_MAKE_PACKAGE_SUPPORTED" && ac_cv_prog_MAKE_PACKAGE_SUPPORTED="no" fi fi MAKE_PACKAGE_SUPPORTED=$ac_cv_prog_MAKE_PACKAGE_SUPPORTED if test -n "$MAKE_PACKAGE_SUPPORTED"; then { echo "$as_me:$LINENO: result: $MAKE_PACKAGE_SUPPORTED" >&5 echo "${ECHO_T}$MAKE_PACKAGE_SUPPORTED" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -x /sbin/sh; then STARTUP_SCRIPT_SHELL=/sbin/sh else STARTUP_SCRIPT_SHELL=/bin/sh fi # System features # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_largefile_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_largefile_CC=' -n32'; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_file_offset_bits+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=no; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=64; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -f conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_large_files+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=no; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=1; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -f conftest* fi fi if test -z "$AR" ; then { { echo "$as_me:$LINENO: error: *** 'ar' missing, please install or fix your \$PATH ***" >&5 echo "$as_me: error: *** 'ar' missing, please install or fix your \$PATH ***" >&2;} { (exit 1); exit 1; }; } fi # Use LOGIN_PROGRAM from environment if possible if test ! -z "$LOGIN_PROGRAM" ; then cat >>confdefs.h <<_ACEOF #define LOGIN_PROGRAM_FALLBACK "$LOGIN_PROGRAM" _ACEOF else # Search for login # Extract the first word of "login", so it can be a program name with args. set dummy login; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_LOGIN_PROGRAM_FALLBACK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $LOGIN_PROGRAM_FALLBACK in [\\/]* | ?:[\\/]*) ac_cv_path_LOGIN_PROGRAM_FALLBACK="$LOGIN_PROGRAM_FALLBACK" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LOGIN_PROGRAM_FALLBACK="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LOGIN_PROGRAM_FALLBACK=$ac_cv_path_LOGIN_PROGRAM_FALLBACK if test -n "$LOGIN_PROGRAM_FALLBACK"; then { echo "$as_me:$LINENO: result: $LOGIN_PROGRAM_FALLBACK" >&5 echo "${ECHO_T}$LOGIN_PROGRAM_FALLBACK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then cat >>confdefs.h <<_ACEOF #define LOGIN_PROGRAM_FALLBACK "$LOGIN_PROGRAM_FALLBACK" _ACEOF fi fi # Extract the first word of "passwd", so it can be a program name with args. set dummy passwd; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PATH_PASSWD_PROG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PATH_PASSWD_PROG in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_PASSWD_PROG="$PATH_PASSWD_PROG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PATH_PASSWD_PROG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PATH_PASSWD_PROG=$ac_cv_path_PATH_PASSWD_PROG if test -n "$PATH_PASSWD_PROG"; then { echo "$as_me:$LINENO: result: $PATH_PASSWD_PROG" >&5 echo "${ECHO_T}$PATH_PASSWD_PROG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test ! -z "$PATH_PASSWD_PROG" ; then cat >>confdefs.h <<_ACEOF #define _PATH_PASSWD_PROG "$PATH_PASSWD_PROG" _ACEOF fi if test -z "$LD" ; then LD=$CC fi { echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6; } if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { echo "$as_me:$LINENO: checking whether LLONG_MAX is declared" >&5 echo $ECHO_N "checking whether LLONG_MAX is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_LLONG_MAX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef LLONG_MAX (void) LLONG_MAX; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_LLONG_MAX=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_LLONG_MAX=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_LLONG_MAX" >&5 echo "${ECHO_T}$ac_cv_have_decl_LLONG_MAX" >&6; } if test $ac_cv_have_decl_LLONG_MAX = yes; then have_llong_max=1 fi { echo "$as_me:$LINENO: checking whether SYSTR_POLICY_KILL is declared" >&5 echo $ECHO_N "checking whether SYSTR_POLICY_KILL is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_SYSTR_POLICY_KILL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { #ifndef SYSTR_POLICY_KILL (void) SYSTR_POLICY_KILL; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_SYSTR_POLICY_KILL=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_SYSTR_POLICY_KILL=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_SYSTR_POLICY_KILL" >&5 echo "${ECHO_T}$ac_cv_have_decl_SYSTR_POLICY_KILL" >&6; } if test $ac_cv_have_decl_SYSTR_POLICY_KILL = yes; then have_systr_policy_kill=1 fi { echo "$as_me:$LINENO: checking whether RLIMIT_NPROC is declared" >&5 echo $ECHO_N "checking whether RLIMIT_NPROC is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_RLIMIT_NPROC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef RLIMIT_NPROC (void) RLIMIT_NPROC; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_RLIMIT_NPROC=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_RLIMIT_NPROC=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_RLIMIT_NPROC" >&5 echo "${ECHO_T}$ac_cv_have_decl_RLIMIT_NPROC" >&6; } if test $ac_cv_have_decl_RLIMIT_NPROC = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_RLIMIT_NPROC _ACEOF fi { echo "$as_me:$LINENO: checking whether PR_SET_NO_NEW_PRIVS is declared" >&5 echo $ECHO_N "checking whether PR_SET_NO_NEW_PRIVS is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_PR_SET_NO_NEW_PRIVS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef PR_SET_NO_NEW_PRIVS (void) PR_SET_NO_NEW_PRIVS; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_PR_SET_NO_NEW_PRIVS=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_PR_SET_NO_NEW_PRIVS=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" >&5 echo "${ECHO_T}$ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" >&6; } if test $ac_cv_have_decl_PR_SET_NO_NEW_PRIVS = yes; then have_linux_no_new_privs=1 fi openssl=yes ssh1=no # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then withval=$with_openssl; if test "x$withval" = "xno" ; then openssl=no ssh1=no fi fi { echo "$as_me:$LINENO: checking whether OpenSSL will be used for cryptography" >&5 echo $ECHO_N "checking whether OpenSSL will be used for cryptography... $ECHO_C" >&6; } if test "x$openssl" = "xyes" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<_ACEOF #define WITH_OPENSSL 1 _ACEOF else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Check whether --with-ssh1 was given. if test "${with_ssh1+set}" = set; then withval=$with_ssh1; if test "x$withval" = "xyes" ; then if test "x$openssl" = "xno" ; then { { echo "$as_me:$LINENO: error: Cannot enable SSH protocol 1 with OpenSSL disabled" >&5 echo "$as_me: error: Cannot enable SSH protocol 1 with OpenSSL disabled" >&2;} { (exit 1); exit 1; }; } fi ssh1=yes elif test "x$withval" = "xno" ; then ssh1=no else { { echo "$as_me:$LINENO: error: unknown --with-ssh1 argument" >&5 echo "$as_me: error: unknown --with-ssh1 argument" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: checking whether SSH protocol 1 support is enabled" >&5 echo $ECHO_N "checking whether SSH protocol 1 support is enabled... $ECHO_C" >&6; } if test "x$ssh1" = "xyes" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<_ACEOF #define WITH_SSH1 1 _ACEOF else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi use_stack_protector=1 use_toolchain_hardening=1 # Check whether --with-stackprotect was given. if test "${with_stackprotect+set}" = set; then withval=$with_stackprotect; if test "x$withval" = "xno"; then use_stack_protector=0 fi fi # Check whether --with-hardening was given. if test "${with_hardening+set}" = set; then withval=$with_hardening; if test "x$withval" = "xno"; then use_toolchain_hardening=0 fi fi # We use -Werror for the tests only so that we catch warnings like "this is # on by default" for things like -fPIE. { echo "$as_me:$LINENO: checking if $CC supports -Werror" >&5 echo $ECHO_N "checking if $CC supports -Werror... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main(void) { return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } WERROR="-Werror" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } WERROR="" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$saved_CFLAGS" if test "$GCC" = "yes" || test "$GCC" = "egcs"; then { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Qunused-arguments" >&5 echo $ECHO_N "checking if $CC supports compile flag -Qunused-arguments... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Qunused-arguments" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Qunused-arguments" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wunknown-warning-option" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wunknown-warning-option... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunknown-warning-option" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wunknown-warning-option" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wall" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wall... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wall" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wall" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wpointer-arith" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wpointer-arith... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-arith" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wpointer-arith" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wuninitialized" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wuninitialized... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wuninitialized" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wuninitialized" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wsign-compare" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wsign-compare... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsign-compare" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsign-compare" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wformat-security" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wformat-security... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wformat-security" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wformat-security" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wsizeof-pointer-memaccess... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsizeof-pointer-memaccess" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsizeof-pointer-memaccess" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wpointer-sign" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wpointer-sign... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-sign" _define_flag="-Wno-pointer-sign" test "x$_define_flag" = "x" && _define_flag="-Wpointer-sign" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wunused-result" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wunused-result... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-result" _define_flag="-Wno-unused-result" test "x$_define_flag" = "x" && _define_flag="-Wunused-result" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -fno-strict-aliasing" >&5 echo $ECHO_N "checking if $CC supports compile flag -fno-strict-aliasing... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fno-strict-aliasing" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-fno-strict-aliasing" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 echo $ECHO_N "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -D_FORTIFY_SOURCE=2" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-D_FORTIFY_SOURCE=2" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } if test "x$use_toolchain_hardening" = "x1"; then { { echo "$as_me:$LINENO: checking if $LD supports link flag -Wl,-z,relro" >&5 echo $ECHO_N "checking if $LD supports link flag -Wl,-z,relro... $ECHO_C" >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,relro" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,relro" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $LD supports link flag -Wl,-z,now" >&5 echo $ECHO_N "checking if $LD supports link flag -Wl,-z,now... $ECHO_C" >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,now" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,now" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 echo $ECHO_N "checking if $LD supports link flag -Wl,-z,noexecstack... $ECHO_C" >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,noexecstack" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,noexecstack" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext } # NB. -ftrapv expects certain support functions to be present in # the compiler library (libgcc or similar) to detect integer operations # that can overflow. We must check that the result of enabling it # actually links. The test program compiled/linked includes a number # of integer operations that should exercise this. { { echo "$as_me:$LINENO: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 echo $ECHO_N "checking if $CC supports compile flag -ftrapv and linking succeeds... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrapv" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-ftrapv" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext } fi { echo "$as_me:$LINENO: checking gcc version" >&5 echo $ECHO_N "checking gcc version... $ECHO_C" >&6; } GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in 1.*) no_attrib_nonnull=1 ;; 2.8* | 2.9*) no_attrib_nonnull=1 ;; 2.*) no_attrib_nonnull=1 ;; *) ;; esac { echo "$as_me:$LINENO: result: $GCC_VER" >&5 echo "${ECHO_T}$GCC_VER" >&6; } { echo "$as_me:$LINENO: checking if $CC accepts -fno-builtin-memset" >&5 echo $ECHO_N "checking if $CC accepts -fno-builtin-memset... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-builtin-memset" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char b[10]; memset(b, 0, sizeof(b)); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # -fstack-protector-all doesn't always work for some GCC versions # and/or platforms, so we test if we can. If it's not supported # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then for t in -fstack-protector-strong -fstack-protector-all \ -fstack-protector; do { echo "$as_me:$LINENO: checking if $CC supports $t" >&5 echo $ECHO_N "checking if $CC supports $t... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" saved_LDFLAGS="$LDFLAGS" CFLAGS="$CFLAGS $t -Werror" LDFLAGS="$LDFLAGS $t -Werror" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char x[256]; snprintf(x, sizeof(x), "XXX"); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $t" LDFLAGS="$saved_LDFLAGS $t" { echo "$as_me:$LINENO: checking if $t works" >&5 echo $ECHO_N "checking if $t works... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: cannot test" >&5 echo "$as_me: WARNING: cross compiling: cannot test" >&2;} break else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char x[256]; snprintf(x, sizeof(x), "XXX"); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } break else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$saved_CFLAGS" LDFLAGS="$saved_LDFLAGS" done fi if test -z "$have_llong_max"; then # retry LLONG_MAX with -std=gnu99, needed on some Linuxes unset ac_cv_have_decl_LLONG_MAX saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -std=gnu99" { echo "$as_me:$LINENO: checking whether LLONG_MAX is declared" >&5 echo $ECHO_N "checking whether LLONG_MAX is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_LLONG_MAX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef LLONG_MAX (void) LLONG_MAX; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_LLONG_MAX=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_LLONG_MAX=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_LLONG_MAX" >&5 echo "${ECHO_T}$ac_cv_have_decl_LLONG_MAX" >&6; } if test $ac_cv_have_decl_LLONG_MAX = yes; then have_llong_max=1 else CFLAGS="$saved_CFLAGS" fi fi fi { echo "$as_me:$LINENO: checking if compiler allows __attribute__ on return types" >&5 echo $ECHO_N "checking if compiler allows __attribute__ on return types... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include __attribute__((__unused__)) static void foo(void){return;} int main () { exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define NO_ATTRIBUTE_ON_RETURN_TYPE 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$no_attrib_nonnull" != "x1" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE__NONNULL__ 1 _ACEOF fi # Check whether --with-rpath was given. if test "${with_rpath+set}" = set; then withval=$with_rpath; if test "x$withval" = "xno" ; then need_dash_r="" fi if test "x$withval" = "xyes" ; then need_dash_r=1 fi fi # Allow user to specify flags # Check whether --with-cflags was given. if test "${with_cflags+set}" = set; then withval=$with_cflags; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then CFLAGS="$CFLAGS $withval" fi fi # Check whether --with-cppflags was given. if test "${with_cppflags+set}" = set; then withval=$with_cppflags; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then CPPFLAGS="$CPPFLAGS $withval" fi fi # Check whether --with-ldflags was given. if test "${with_ldflags+set}" = set; then withval=$with_ldflags; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then LDFLAGS="$LDFLAGS $withval" fi fi # Check whether --with-libs was given. if test "${with_libs+set}" = set; then withval=$with_libs; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then LIBS="$LIBS $withval" fi fi # Check whether --with-Werror was given. if test "${with_Werror+set}" = set; then withval=$with_Werror; if test -n "$withval" && test "x$withval" != "xno"; then werror_flags="-Werror" if test "x${withval}" != "xyes"; then werror_flags="$withval" fi fi fi for ac_header in \ blf.h \ bstring.h \ crypt.h \ crypto/sha2.h \ dirent.h \ endian.h \ elf.h \ features.h \ fcntl.h \ floatingpoint.h \ getopt.h \ glob.h \ ia.h \ iaf.h \ inttypes.h \ limits.h \ locale.h \ login.h \ maillock.h \ ndir.h \ net/if_tun.h \ netdb.h \ netgroup.h \ pam/pam_appl.h \ paths.h \ poll.h \ pty.h \ readpassphrase.h \ rpc/types.h \ security/pam_appl.h \ sha2.h \ shadow.h \ stddef.h \ stdint.h \ string.h \ strings.h \ sys/audit.h \ sys/bitypes.h \ sys/bsdtty.h \ sys/capability.h \ sys/cdefs.h \ sys/dir.h \ sys/mman.h \ sys/ndir.h \ sys/poll.h \ sys/prctl.h \ sys/pstat.h \ sys/select.h \ sys/stat.h \ sys/stream.h \ sys/stropts.h \ sys/strtio.h \ sys/statvfs.h \ sys/sysmacros.h \ sys/time.h \ sys/timers.h \ time.h \ tmpdir.h \ ttyent.h \ ucred.h \ unistd.h \ usersec.h \ util.h \ utime.h \ utmp.h \ utmpx.h \ vis.h \ do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # lastlog.h requires sys/time.h to be included first on Solaris for ac_header in lastlog.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TIME_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # sys/ptms.h requires sys/stream.h to be included first on Solaris for ac_header in sys/ptms.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_STREAM_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # login_cap.h requires sys/types.h on NetBSD for ac_header in login_cap.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # older BSDs need sys/param.h before sys/mount.h for ac_header in sys/mount.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Android requires sys/socket.h to be included before sys/un.h for ac_header in sys/un.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Messages for features tested for in target-specific section SIA_MSG="no" SPC_MSG="no" SP_MSG="no" SPP_MSG="no" # Support for Solaris/Illumos privileges (this test is used by both # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" # Check for some target-specific stuff case "$host" in *-*-aix*) # Some versions of VAC won't allow macro redefinitions at # -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that # particularly with older versions of vac or xlc. # It also throws errors about null macro argments, but these are # not fatal. { echo "$as_me:$LINENO: checking if compiler allows macro redefinitions" >&5 echo $ECHO_N "checking if compiler allows macro redefinitions... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define testmacro foo #define testmacro bar int main () { exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`" LD="`echo $LD | sed 's/-qlanglvl\=ansi//g'`" CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`" CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: checking how to specify blibpath for linker ($LD)" >&5 echo $ECHO_N "checking how to specify blibpath for linker ($LD)... $ECHO_C" >&6; } if (test -z "$blibpath"); then blibpath="/usr/lib:/lib" fi saved_LDFLAGS="$LDFLAGS" if test "$GCC" = "yes"; then flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:" else flags="-blibpath: -Wl,-blibpath: -Wl,-rpath," fi for tryflags in $flags ;do if (test -z "$blibflags"); then LDFLAGS="$saved_LDFLAGS $tryflags$blibpath" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then blibflags=$tryflags else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi done if (test -z "$blibflags"); then { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: *** must be able to specify blibpath on AIX - check config.log" >&5 echo "$as_me: error: *** must be able to specify blibpath on AIX - check config.log" >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: $blibflags" >&5 echo "${ECHO_T}$blibflags" >&6; } fi LDFLAGS="$saved_LDFLAGS" { echo "$as_me:$LINENO: checking for authenticate" >&5 echo $ECHO_N "checking for authenticate... $ECHO_C" >&6; } if test "${ac_cv_func_authenticate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define authenticate to an innocuous variant, in case declares authenticate. For example, HP-UX 11i declares gettimeofday. */ #define authenticate innocuous_authenticate /* System header to define __stub macros and hopefully few prototypes, which can conflict with char authenticate (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef authenticate /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char authenticate (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_authenticate || defined __stub___authenticate choke me #endif int main () { return authenticate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_authenticate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_authenticate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_authenticate" >&5 echo "${ECHO_T}$ac_cv_func_authenticate" >&6; } if test $ac_cv_func_authenticate = yes; then cat >>confdefs.h <<\_ACEOF #define WITH_AIXAUTHENTICATE 1 _ACEOF else { echo "$as_me:$LINENO: checking for authenticate in -ls" >&5 echo $ECHO_N "checking for authenticate in -ls... $ECHO_C" >&6; } if test "${ac_cv_lib_s_authenticate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ls $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char authenticate (); int main () { return authenticate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_s_authenticate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_s_authenticate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_s_authenticate" >&5 echo "${ECHO_T}$ac_cv_lib_s_authenticate" >&6; } if test $ac_cv_lib_s_authenticate = yes; then cat >>confdefs.h <<\_ACEOF #define WITH_AIXAUTHENTICATE 1 _ACEOF LIBS="$LIBS -ls" fi fi { echo "$as_me:$LINENO: checking whether authenticate is declared" >&5 echo $ECHO_N "checking whether authenticate is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_authenticate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef authenticate (void) authenticate; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_authenticate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_authenticate=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_authenticate" >&5 echo "${ECHO_T}$ac_cv_have_decl_authenticate" >&6; } if test $ac_cv_have_decl_authenticate = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AUTHENTICATE 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AUTHENTICATE 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether loginrestrictions is declared" >&5 echo $ECHO_N "checking whether loginrestrictions is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_loginrestrictions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef loginrestrictions (void) loginrestrictions; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_loginrestrictions=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_loginrestrictions=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_loginrestrictions" >&5 echo "${ECHO_T}$ac_cv_have_decl_loginrestrictions" >&6; } if test $ac_cv_have_decl_loginrestrictions = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINRESTRICTIONS 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINRESTRICTIONS 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether loginsuccess is declared" >&5 echo $ECHO_N "checking whether loginsuccess is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_loginsuccess+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef loginsuccess (void) loginsuccess; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_loginsuccess=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_loginsuccess=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_loginsuccess" >&5 echo "${ECHO_T}$ac_cv_have_decl_loginsuccess" >&6; } if test $ac_cv_have_decl_loginsuccess = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINSUCCESS 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINSUCCESS 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether passwdexpired is declared" >&5 echo $ECHO_N "checking whether passwdexpired is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_passwdexpired+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef passwdexpired (void) passwdexpired; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_passwdexpired=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_passwdexpired=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_passwdexpired" >&5 echo "${ECHO_T}$ac_cv_have_decl_passwdexpired" >&6; } if test $ac_cv_have_decl_passwdexpired = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PASSWDEXPIRED 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PASSWDEXPIRED 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether setauthdb is declared" >&5 echo $ECHO_N "checking whether setauthdb is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_setauthdb+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef setauthdb (void) setauthdb; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_setauthdb=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_setauthdb=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_setauthdb" >&5 echo "${ECHO_T}$ac_cv_have_decl_setauthdb" >&6; } if test $ac_cv_have_decl_setauthdb = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETAUTHDB 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETAUTHDB 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether loginfailed is declared" >&5 echo $ECHO_N "checking whether loginfailed is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_loginfailed+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef loginfailed (void) loginfailed; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_loginfailed=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_loginfailed=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_loginfailed" >&5 echo "${ECHO_T}$ac_cv_have_decl_loginfailed" >&6; } if test $ac_cv_have_decl_loginfailed = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINFAILED 1 _ACEOF { echo "$as_me:$LINENO: checking if loginfailed takes 4 arguments" >&5 echo $ECHO_N "checking if loginfailed takes 4 arguments... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { (void)loginfailed("user","host","tty",0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define AIX_LOGINFAILED_4ARG 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINFAILED 0 _ACEOF fi for ac_func in getgrset setauthdb do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether F_CLOSEM is declared" >&5 echo $ECHO_N "checking whether F_CLOSEM is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_F_CLOSEM+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef F_CLOSEM (void) F_CLOSEM; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_F_CLOSEM=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_F_CLOSEM=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_F_CLOSEM" >&5 echo "${ECHO_T}$ac_cv_have_decl_F_CLOSEM" >&6; } if test $ac_cv_have_decl_F_CLOSEM = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_FCNTL_CLOSEM 1 _ACEOF fi check_for_aix_broken_getaddrinfo=1 cat >>confdefs.h <<\_ACEOF #define BROKEN_REALPATH 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_LASTLOG 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOGIN_NEEDS_UTMPX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SPT_TYPE SPT_REUSEARGV _ACEOF cat >>confdefs.h <<\_ACEOF #define SSHPAM_CHAUTHTOK_NEEDS_RUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PTY_ZEROREAD 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PLATFORM_SYS_DIR_UID 2 _ACEOF ;; *-*-android*) cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMP 1 _ACEOF ;; *-*-cygwin*) check_for_libcrypt_later=1 LIBS="$LIBS /usr/lib/textreadmode.o" cat >>confdefs.h <<\_ACEOF #define HAVE_CYGWIN 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NO_UID_RESTORATION_TEST 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_SHADOW 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NO_X11_UNIX_SOCKETS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NO_IPPORT_RESERVED_CONCEPT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_IOBUFSZ 65535 _ACEOF cat >>confdefs.h <<\_ACEOF #define FILESYSTEM_NO_BACKSLASH 1 _ACEOF # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. { { echo "$as_me:$LINENO: checking if $CC supports compile flag -Wno-attributes" >&5 echo $ECHO_N "checking if $CC supports compile flag -Wno-attributes... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-attributes" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wno-attributes" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } ;; *-*-dgux*) cat >>confdefs.h <<\_ACEOF #define IP_TOS_IS_BROKEN 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF ;; *-*-darwin*) use_pie=auto { echo "$as_me:$LINENO: checking if we have working getaddrinfo" >&5 echo $ECHO_N "checking if we have working getaddrinfo... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: assume it is working" >&5 echo "${ECHO_T}assume it is working" >&6; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) exit(0); else exit(1); } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: working" >&5 echo "${ECHO_T}working" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: buggy" >&5 echo "${ECHO_T}buggy" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_GLOB 1 _ACEOF cat >>confdefs.h <<_ACEOF #define BIND_8_COMPAT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_FREEBSD 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_COMPAT_AF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_PREPEND_AF 1 _ACEOF { echo "$as_me:$LINENO: checking whether AU_IPv4 is declared" >&5 echo $ECHO_N "checking whether AU_IPv4 is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_AU_IPv4+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef AU_IPv4 (void) AU_IPv4; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_AU_IPv4=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_AU_IPv4=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_AU_IPv4" >&5 echo "${ECHO_T}$ac_cv_have_decl_AU_IPv4" >&6; } if test $ac_cv_have_decl_AU_IPv4 = yes; then : else cat >>confdefs.h <<\_ACEOF #define AU_IPv4 0 _ACEOF #include cat >>confdefs.h <<\_ACEOF #define LASTLOG_WRITE_PUTUTXLINE 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define SPT_TYPE SPT_REUSEARGV _ACEOF for ac_func in sandbox_init do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sandbox.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for sandbox_apply in -lsandbox" >&5 echo $ECHO_N "checking for sandbox_apply in -lsandbox... $ECHO_C" >&6; } if test "${ac_cv_lib_sandbox_sandbox_apply+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsandbox $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sandbox_apply (); int main () { return sandbox_apply (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_sandbox_sandbox_apply=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sandbox_sandbox_apply=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_sandbox_sandbox_apply" >&5 echo "${ECHO_T}$ac_cv_lib_sandbox_sandbox_apply" >&6; } if test $ac_cv_lib_sandbox_sandbox_apply = yes; then SSHDLIBS="$SSHDLIBS -lsandbox" fi ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-haiku*) LIBS="$LIBS -lbsd " { echo "$as_me:$LINENO: checking for socket in -lnetwork" >&5 echo $ECHO_N "checking for socket in -lnetwork... $ECHO_C" >&6; } if test "${ac_cv_lib_network_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnetwork $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_network_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_network_socket=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_network_socket" >&5 echo "${ECHO_T}$ac_cv_lib_network_socket" >&6; } if test $ac_cv_lib_network_socket = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNETWORK 1 _ACEOF LIBS="-lnetwork $LIBS" fi cat >>confdefs.h <<\_ACEOF #define HAVE_U_INT64_T 1 _ACEOF MANTYPE=man ;; *-*-hpux*) # first we define all of the options common to all HP-UX releases CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" IPADDR_IN_DISPLAY=yes cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOGIN_NO_ENDOPT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOGIN_NEEDS_UTMPX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*" _ACEOF cat >>confdefs.h <<\_ACEOF #define SPT_TYPE SPT_PSTAT _ACEOF cat >>confdefs.h <<\_ACEOF #define PLATFORM_SYS_DIR_UID 2 _ACEOF maildir="/var/mail" LIBS="$LIBS -lsec" { echo "$as_me:$LINENO: checking for t_error in -lxnet" >&5 echo $ECHO_N "checking for t_error in -lxnet... $ECHO_C" >&6; } if test "${ac_cv_lib_xnet_t_error+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxnet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char t_error (); int main () { return t_error (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_xnet_t_error=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_xnet_t_error=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_xnet_t_error" >&5 echo "${ECHO_T}$ac_cv_lib_xnet_t_error" >&6; } if test $ac_cv_lib_xnet_t_error = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBXNET 1 _ACEOF LIBS="-lxnet $LIBS" else { { echo "$as_me:$LINENO: error: *** -lxnet needed on HP-UX - check config.log ***" >&5 echo "$as_me: error: *** -lxnet needed on HP-UX - check config.log ***" >&2;} { (exit 1); exit 1; }; } fi # next, we define all of the options specific to major releases case "$host" in *-*-hpux10*) if test -z "$GCC"; then CFLAGS="$CFLAGS -Ae" fi ;; *-*-hpux11*) cat >>confdefs.h <<\_ACEOF #define PAM_SUN_CODEBASE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_BTMP 1 _ACEOF check_for_hpux_broken_getaddrinfo=1 check_for_conflicting_getspnam=1 ;; esac # lastly, we define options specific to minor releases case "$host" in *-*-hpux10.26) cat >>confdefs.h <<\_ACEOF #define HAVE_SECUREWARE 1 _ACEOF disable_ptmx_check=yes LIBS="$LIBS -lsecpw" ;; esac ;; *-*-irix5*) PATH="$PATH:/usr/etc" cat >>confdefs.h <<\_ACEOF #define BROKEN_INET_NTOA 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_ABBREV_NO_TTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF ;; *-*-irix6*) PATH="$PATH:/usr/etc" cat >>confdefs.h <<\_ACEOF #define WITH_IRIX_ARRAY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_IRIX_PROJECT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_IRIX_AUDIT 1 _ACEOF { echo "$as_me:$LINENO: checking for jlimit_startjob" >&5 echo $ECHO_N "checking for jlimit_startjob... $ECHO_C" >&6; } if test "${ac_cv_func_jlimit_startjob+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define jlimit_startjob to an innocuous variant, in case declares jlimit_startjob. For example, HP-UX 11i declares gettimeofday. */ #define jlimit_startjob innocuous_jlimit_startjob /* System header to define __stub macros and hopefully few prototypes, which can conflict with char jlimit_startjob (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef jlimit_startjob /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jlimit_startjob (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_jlimit_startjob || defined __stub___jlimit_startjob choke me #endif int main () { return jlimit_startjob (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_jlimit_startjob=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_jlimit_startjob=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_jlimit_startjob" >&5 echo "${ECHO_T}$ac_cv_func_jlimit_startjob" >&6; } if test $ac_cv_func_jlimit_startjob = yes; then cat >>confdefs.h <<\_ACEOF #define WITH_IRIX_JOBS 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define BROKEN_INET_NTOA 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_UPDWTMPX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_ABBREV_NO_TTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF ;; *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) check_for_libcrypt_later=1 cat >>confdefs.h <<\_ACEOF #define PAM_TTY_KLUDGE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_PREFIX "!" _ACEOF cat >>confdefs.h <<\_ACEOF #define SPT_TYPE SPT_REUSEARGV _ACEOF cat >>confdefs.h <<\_ACEOF #define _PATH_BTMP "/var/log/btmp" _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_BTMP 1 _ACEOF ;; *-*-linux*) no_dev_ptmx=1 use_pie=auto check_for_libcrypt_later=1 check_for_openpty_ctty_bug=1 cat >>confdefs.h <<\_ACEOF #define PAM_TTY_KLUDGE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_PREFIX "!" _ACEOF cat >>confdefs.h <<\_ACEOF #define SPT_TYPE SPT_REUSEARGV _ACEOF cat >>confdefs.h <<\_ACEOF #define LINK_OPNOTSUPP_ERRNO EPERM _ACEOF cat >>confdefs.h <<\_ACEOF #define _PATH_BTMP "/var/log/btmp" _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_BTMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LINUX_OOM_ADJUST 1 _ACEOF inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) cat >>confdefs.h <<\_ACEOF #define BROKEN_CMSG_TYPE 1 _ACEOF ;; esac # tun(4) forwarding compat code for ac_header in linux/if_tun.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define SSH_TUN_LINUX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_COMPAT_AF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_PREPEND_AF 1 _ACEOF fi for ac_header in linux/seccomp.h linux/filter.h linux/audit.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in prctl do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for seccomp architecture" >&5 echo $ECHO_N "checking for seccomp architecture... $ECHO_C" >&6; } seccomp_audit_arch= case "$host" in x86_64-*) seccomp_audit_arch=AUDIT_ARCH_X86_64 ;; i*86-*) seccomp_audit_arch=AUDIT_ARCH_I386 ;; arm*-*) seccomp_audit_arch=AUDIT_ARCH_ARM ;; aarch64*-*) seccomp_audit_arch=AUDIT_ARCH_AARCH64 ;; esac if test "x$seccomp_audit_arch" != "x" ; then { echo "$as_me:$LINENO: result: \"$seccomp_audit_arch\"" >&5 echo "${ECHO_T}\"$seccomp_audit_arch\"" >&6; } cat >>confdefs.h <<_ACEOF #define SECCOMP_AUDIT_ARCH $seccomp_audit_arch _ACEOF else { echo "$as_me:$LINENO: result: architecture not supported" >&5 echo "${ECHO_T}architecture not supported" >&6; } fi ;; mips-sony-bsd|mips-sony-newsos4) cat >>confdefs.h <<\_ACEOF #define NEED_SETPGRP 1 _ACEOF SONY=1 ;; *-*-netbsd*) check_for_libcrypt_before=1 if test "x$withval" != "xno" ; then need_dash_r=1 fi cat >>confdefs.h <<\_ACEOF #define SSH_TUN_FREEBSD 1 _ACEOF if test "${ac_cv_header_net_if_tap_h+set}" = set; then { echo "$as_me:$LINENO: checking for net/if_tap.h" >&5 echo $ECHO_N "checking for net/if_tap.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_if_tap_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_if_tap_h" >&5 echo "${ECHO_T}$ac_cv_header_net_if_tap_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking net/if_tap.h usability" >&5 echo $ECHO_N "checking net/if_tap.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking net/if_tap.h presence" >&5 echo $ECHO_N "checking net/if_tap.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/if_tap.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/if_tap.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/if_tap.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/if_tap.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/if_tap.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/if_tap.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/if_tap.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/if_tap.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/if_tap.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/if_tap.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for net/if_tap.h" >&5 echo $ECHO_N "checking for net/if_tap.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_if_tap_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_if_tap_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_if_tap_h" >&5 echo "${ECHO_T}$ac_cv_header_net_if_tap_h" >&6; } fi if test $ac_cv_header_net_if_tap_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define SSH_TUN_NO_L2 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define SSH_TUN_PREPEND_AF 1 _ACEOF TEST_MALLOC_OPTIONS="AJRX" cat >>confdefs.h <<\_ACEOF #define BROKEN_STRNVIS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_READ_COMPARISON 1 _ACEOF ;; *-*-freebsd*) check_for_libcrypt_later=1 cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_PREFIX "*LOCKED*" _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_FREEBSD 1 _ACEOF if test "${ac_cv_header_net_if_tap_h+set}" = set; then { echo "$as_me:$LINENO: checking for net/if_tap.h" >&5 echo $ECHO_N "checking for net/if_tap.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_if_tap_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_if_tap_h" >&5 echo "${ECHO_T}$ac_cv_header_net_if_tap_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking net/if_tap.h usability" >&5 echo $ECHO_N "checking net/if_tap.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking net/if_tap.h presence" >&5 echo $ECHO_N "checking net/if_tap.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/if_tap.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/if_tap.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/if_tap.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/if_tap.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/if_tap.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/if_tap.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/if_tap.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/if_tap.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/if_tap.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/if_tap.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/if_tap.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for net/if_tap.h" >&5 echo $ECHO_N "checking for net/if_tap.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_if_tap_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_if_tap_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_if_tap_h" >&5 echo "${ECHO_T}$ac_cv_header_net_if_tap_h" >&6; } fi if test $ac_cv_header_net_if_tap_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define SSH_TUN_NO_L2 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define BROKEN_GLOB 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_STRNVIS 1 _ACEOF TEST_MALLOC_OPTIONS="AJRX" # Preauth crypto occasionally uses file descriptors for crypto offload # and will crash if they cannot be opened. cat >>confdefs.h <<\_ACEOF #define SANDBOX_SKIP_RLIMIT_NOFILE 1 _ACEOF ;; *-*-bsdi*) cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF ;; *-next-*) conf_lastlog_location="/usr/adm/lastlog" conf_utmp_location=/etc/utmp conf_wtmp_location=/usr/adm/wtmp maildir=/usr/spool/mail cat >>confdefs.h <<\_ACEOF #define HAVE_NEXT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_REALPATH 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SAVED_UIDS 1 _ACEOF ;; *-*-openbsd*) use_pie=auto cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE__SENTINEL__ 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE__BOUNDED__ 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSH_TUN_OPENBSD 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SYSLOG_R_SAFE_IN_SIGHAND 1 _ACEOF TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-solaris*) if test "x$withval" != "xno" ; then need_dash_r=1 fi cat >>confdefs.h <<\_ACEOF #define PAM_SUN_CODEBASE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOGIN_NEEDS_UTMPX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOGIN_NEEDS_TERM 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PAM_TTY_KLUDGE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSHPAM_CHAUTHTOK_NEEDS_RUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF # Pushing STREAMS modules will cause sshd to acquire a controlling tty. cat >>confdefs.h <<\_ACEOF #define SSHD_ACQUIRES_CTTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PASSWD_NEEDS_USERNAME 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_TCGETATTR_ICANON 1 _ACEOF external_path_file=/etc/default/login # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" { echo "$as_me:$LINENO: checking for obsolete utmp and wtmp in solaris2.x" >&5 echo $ECHO_N "checking for obsolete utmp and wtmp in solaris2.x... $ECHO_C" >&6; } sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` if test "$sol2ver" -ge 8; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMP 1 _ACEOF else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi for ac_func in setppriv do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in priv_basicset do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in priv.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Check whether --with-solaris-contracts was given. if test "${with_solaris_contracts+set}" = set; then withval=$with_solaris_contracts; { echo "$as_me:$LINENO: checking for ct_tmpl_activate in -lcontract" >&5 echo $ECHO_N "checking for ct_tmpl_activate in -lcontract... $ECHO_C" >&6; } if test "${ac_cv_lib_contract_ct_tmpl_activate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcontract $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ct_tmpl_activate (); int main () { return ct_tmpl_activate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_contract_ct_tmpl_activate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_contract_ct_tmpl_activate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_contract_ct_tmpl_activate" >&5 echo "${ECHO_T}$ac_cv_lib_contract_ct_tmpl_activate" >&6; } if test $ac_cv_lib_contract_ct_tmpl_activate = yes; then cat >>confdefs.h <<\_ACEOF #define USE_SOLARIS_PROCESS_CONTRACTS 1 _ACEOF LIBS="$LIBS -lcontract" SPC_MSG="yes" fi fi # Check whether --with-solaris-projects was given. if test "${with_solaris_projects+set}" = set; then withval=$with_solaris_projects; { echo "$as_me:$LINENO: checking for setproject in -lproject" >&5 echo $ECHO_N "checking for setproject in -lproject... $ECHO_C" >&6; } if test "${ac_cv_lib_project_setproject+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproject $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setproject (); int main () { return setproject (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_project_setproject=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_project_setproject=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_project_setproject" >&5 echo "${ECHO_T}$ac_cv_lib_project_setproject" >&6; } if test $ac_cv_lib_project_setproject = yes; then cat >>confdefs.h <<\_ACEOF #define USE_SOLARIS_PROJECTS 1 _ACEOF LIBS="$LIBS -lproject" SP_MSG="yes" fi fi # Check whether --with-solaris-privs was given. if test "${with_solaris_privs+set}" = set; then withval=$with_solaris_privs; { echo "$as_me:$LINENO: checking for Solaris/Illumos privilege support" >&5 echo $ECHO_N "checking for Solaris/Illumos privilege support... $ECHO_C" >&6; } if test "x$ac_cv_func_setppriv" = "xyes" -a \ "x$ac_cv_header_priv_h" = "xyes" ; then SOLARIS_PRIVS=yes { echo "$as_me:$LINENO: result: found" >&5 echo "${ECHO_T}found" >&6; } cat >>confdefs.h <<\_ACEOF #define NO_UID_RESTORATION_TEST 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_SOLARIS_PRIVS 1 _ACEOF SPP_MSG="yes" else { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&5 echo "$as_me: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&2;} { (exit 1); exit 1; }; } fi fi TEST_SHELL=$SHELL # let configure find us a capable shell ;; *-*-sunos4*) CPPFLAGS="$CPPFLAGS -DSUNOS4" for ac_func in getpwanam do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done cat >>confdefs.h <<\_ACEOF #define PAM_SUN_CODEBASE 1 _ACEOF conf_utmp_location=/etc/utmp conf_wtmp_location=/var/adm/wtmp conf_lastlog_location=/var/adm/lastlog cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF ;; *-ncr-sysv*) LIBS="$LIBS -lc89" cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSHD_ACQUIRES_CTTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF ;; *-sni-sysv*) # /usr/ucblib MUST NOT be searched on ReliantUNIX { echo "$as_me:$LINENO: checking for dlsym in -ldl" >&5 echo $ECHO_N "checking for dlsym in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlsym+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlsym (); int main () { return dlsym (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlsym=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlsym=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlsym" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlsym" >&6; } if test $ac_cv_lib_dl_dlsym = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi # -lresolv needs to be at the end of LIBS or DNS lookups break { echo "$as_me:$LINENO: checking for res_query in -lresolv" >&5 echo $ECHO_N "checking for res_query in -lresolv... $ECHO_C" >&6; } if test "${ac_cv_lib_resolv_res_query+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char res_query (); int main () { return res_query (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_resolv_res_query=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_res_query=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_query" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_res_query" >&6; } if test $ac_cv_lib_resolv_res_query = yes; then LIBS="$LIBS -lresolv" fi IPADDR_IN_DISPLAY=yes cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define IP_TOS_IS_BROKEN 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSHD_ACQUIRES_CTTY 1 _ACEOF external_path_file=/etc/default/login # /usr/ucblib/libucb.a no longer needed on ReliantUNIX # Attention: always take care to bind libsocket and libnsl before libc, # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog ;; # UnixWare 1.x, UnixWare 2.x, and others based on code from Univel. *-*-sysv4.2*) cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PASSWD_NEEDS_USERNAME 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF TEST_SHELL=$SHELL # let configure find us a capable shell ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf" cat >>confdefs.h <<\_ACEOF #define UNIXWARE_LONG_PASSWORDS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PASSWD_NEEDS_USERNAME 1 _ACEOF TEST_SHELL=$SHELL # let configure find us a capable shell case "$host" in *-*-sysv5SCO_SV*) # SCO OpenServer 6.x maildir=/var/spool/mail cat >>confdefs.h <<\_ACEOF #define BROKEN_LIBIAF 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_UPDWTMPX 1 _ACEOF { echo "$as_me:$LINENO: checking for getluid in -lprot" >&5 echo $ECHO_N "checking for getluid in -lprot... $ECHO_C" >&6; } if test "${ac_cv_lib_prot_getluid+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lprot $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getluid (); int main () { return getluid (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_prot_getluid=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_prot_getluid=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_prot_getluid" >&5 echo "${ECHO_T}$ac_cv_lib_prot_getluid" >&6; } if test $ac_cv_lib_prot_getluid = yes; then LIBS="$LIBS -lprot" for ac_func in getluid setluid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done cat >>confdefs.h <<\_ACEOF #define HAVE_SECUREWARE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_SHADOW 1 _ACEOF fi ;; *) cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF check_for_libcrypt_later=1 ;; esac ;; *-*-sysv*) ;; # SCO UNIX and OEM versions of SCO UNIX *-*-sco3.2v4*) { { echo "$as_me:$LINENO: error: \"This Platform is no longer supported.\"" >&5 echo "$as_me: error: \"This Platform is no longer supported.\"" >&2;} { (exit 1); exit 1; }; } ;; # SCO OpenServer 5.x *-*-sco3.2v5*) if test -z "$GCC"; then CFLAGS="$CFLAGS -belf" fi LIBS="$LIBS -lprot -lx -ltinfo -lm" no_dev_ptmx=1 cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_SECUREWARE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_SHADOW 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_ABBREV_NO_TTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_UPDWTMPX 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define PASSWD_NEEDS_USERNAME 1 _ACEOF for ac_func in getluid setluid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done MANTYPE=man TEST_SHELL=$SHELL # let configure find us a capable shell SKIP_DISABLE_LASTLOG_DEFINE=yes ;; *-*-unicosmk*) cat >>confdefs.h <<\_ACEOF #define NO_SSH_LASTLOG 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-*-unicosmp*) cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define WITH_ABBREV_NO_TTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lacid -ldb" MANTYPE=cat ;; *-*-unicos*) cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NO_SSH_LASTLOG 1 _ACEOF LDFLAGS="$LDFLAGS -Wl,-Dmsglevel=334:fatal" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-dec-osf*) { echo "$as_me:$LINENO: checking for Digital Unix SIA" >&5 echo $ECHO_N "checking for Digital Unix SIA... $ECHO_C" >&6; } no_osfsia="" # Check whether --with-osfsia was given. if test "${with_osfsia+set}" = set; then withval=$with_osfsia; if test "x$withval" = "xno" ; then { echo "$as_me:$LINENO: result: disabled" >&5 echo "${ECHO_T}disabled" >&6; } no_osfsia=1 fi fi if test -z "$no_osfsia" ; then if test -f /etc/sia/matrix.conf; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_OSF_SIA 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_LOGIN 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF LIBS="$LIBS -lsecurity -ldb -lm -laud" SIA_MSG="yes" else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_SUBSTR "Nologin" _ACEOF fi fi cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SETEUID_BREAKS_SETUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREUID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SETREGID 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_READV_COMPARISON 1 _ACEOF ;; *-*-nto-qnx*) cat >>confdefs.h <<\_ACEOF #define USE_PIPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NO_X11_UNIX_SOCKETS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_LASTLOG 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SSHD_ACQUIRES_CTTY 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_SHADOW_EXPIRE 1 _ACEOF enable_etc_default_login=no # has incompatible /etc/default/login case "$host" in *-*-nto-qnx6*) cat >>confdefs.h <<\_ACEOF #define DISABLE_FD_PASSING 1 _ACEOF ;; esac ;; *-*-ultrix*) cat >>confdefs.h <<\_ACEOF #define BROKEN_GETGROUPS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define BROKEN_MMAP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define NEED_SETPGRP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_SYSLOG_H 1 _ACEOF ;; *-*-lynxos) CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" cat >>confdefs.h <<\_ACEOF #define BROKEN_SETVBUF 1 _ACEOF ;; esac { echo "$as_me:$LINENO: checking compiler and flags for sanity" >&5 echo $ECHO_N "checking compiler and flags for sanity... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking compiler sanity" >&5 echo "$as_me: WARNING: cross compiling: not checking compiler sanity" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: *** compiler cannot create working executables, check config.log ***" >&5 echo "$as_me: error: *** compiler cannot create working executables, check config.log ***" >&2;} { (exit 1); exit 1; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi # Checks for libraries. { echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6; } if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_setsockopt || defined __stub___setsockopt choke me #endif int main () { return setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6; } if test $ac_cv_func_setsockopt = yes; then : else { echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6; } if test $ac_cv_lib_socket_setsockopt = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi for ac_func in dirname do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF for ac_header in libgen.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done else { echo "$as_me:$LINENO: checking for dirname in -lgen" >&5 echo $ECHO_N "checking for dirname in -lgen... $ECHO_C" >&6; } if test "${ac_cv_lib_gen_dirname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dirname (); int main () { return dirname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gen_dirname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gen_dirname=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gen_dirname" >&5 echo "${ECHO_T}$ac_cv_lib_gen_dirname" >&6; } if test $ac_cv_lib_gen_dirname = yes; then { echo "$as_me:$LINENO: checking for broken dirname" >&5 echo $ECHO_N "checking for broken dirname... $ECHO_C" >&6; } if test "${ac_cv_have_broken_dirname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else save_LIBS="$LIBS" LIBS="$LIBS -lgen" if test "$cross_compiling" = yes; then ac_cv_have_broken_dirname="no" else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { char *s, buf[32]; strncpy(buf,"/etc", 32); s = dirname(buf); if (!s || strncmp(s, "/", 32) != 0) { exit(1); } else { exit(0); } } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_have_broken_dirname="no" else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_have_broken_dirname="yes" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi LIBS="$save_LIBS" fi { echo "$as_me:$LINENO: result: $ac_cv_have_broken_dirname" >&5 echo "${ECHO_T}$ac_cv_have_broken_dirname" >&6; } if test "x$ac_cv_have_broken_dirname" = "xno" ; then LIBS="$LIBS -lgen" cat >>confdefs.h <<\_ACEOF #define HAVE_DIRNAME 1 _ACEOF for ac_header in libgen.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done fi fi fi done { echo "$as_me:$LINENO: checking for getspnam" >&5 echo $ECHO_N "checking for getspnam... $ECHO_C" >&6; } if test "${ac_cv_func_getspnam+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define getspnam to an innocuous variant, in case declares getspnam. For example, HP-UX 11i declares gettimeofday. */ #define getspnam innocuous_getspnam /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getspnam (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef getspnam /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getspnam (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_getspnam || defined __stub___getspnam choke me #endif int main () { return getspnam (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_getspnam=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_getspnam=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_getspnam" >&5 echo "${ECHO_T}$ac_cv_func_getspnam" >&6; } if test $ac_cv_func_getspnam = yes; then : else { echo "$as_me:$LINENO: checking for getspnam in -lgen" >&5 echo $ECHO_N "checking for getspnam in -lgen... $ECHO_C" >&6; } if test "${ac_cv_lib_gen_getspnam+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getspnam (); int main () { return getspnam (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gen_getspnam=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gen_getspnam=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gen_getspnam" >&5 echo "${ECHO_T}$ac_cv_lib_gen_getspnam" >&6; } if test $ac_cv_lib_gen_getspnam = yes; then LIBS="$LIBS -lgen" fi fi { echo "$as_me:$LINENO: checking for library containing basename" >&5 echo $ECHO_N "checking for library containing basename... $ECHO_C" >&6; } if test "${ac_cv_search_basename+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char basename (); int main () { return basename (); ; return 0; } _ACEOF for ac_lib in '' gen; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_basename=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_basename+set}" = set; then break fi done if test "${ac_cv_search_basename+set}" = set; then : else ac_cv_search_basename=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_basename" >&5 echo "${ECHO_T}$ac_cv_search_basename" >&6; } ac_res=$ac_cv_search_basename if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_BASENAME 1 _ACEOF fi # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then withval=$with_zlib; if test "x$withval" = "xno" ; then { { echo "$as_me:$LINENO: error: *** zlib is required ***" >&5 echo "$as_me: error: *** zlib is required ***" >&2;} { (exit 1); exit 1; }; } elif test "x$withval" != "xyes"; then if test -d "$withval/lib"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi else if test -n "${need_dash_r}"; then LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" else LDFLAGS="-L${withval} ${LDFLAGS}" fi fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include ${CPPFLAGS}" else CPPFLAGS="-I${withval} ${CPPFLAGS}" fi fi fi if test "${ac_cv_header_zlib_h+set}" = set; then { echo "$as_me:$LINENO: checking for zlib.h" >&5 echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_zlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking zlib.h usability" >&5 echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking zlib.h presence" >&5 echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for zlib.h" >&5 echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_zlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_zlib_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; } fi if test $ac_cv_header_zlib_h = yes; then : else { { echo "$as_me:$LINENO: error: *** zlib.h missing - please install first or check config.log ***" >&5 echo "$as_me: error: *** zlib.h missing - please install first or check config.log ***" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for deflate in -lz" >&5 echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; } if test "${ac_cv_lib_z_deflate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_z_deflate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5 echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6; } if test $ac_cv_lib_z_deflate = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" if test -n "${need_dash_r}"; then LDFLAGS="-L/usr/local/lib -R/usr/local/lib ${saved_LDFLAGS}" else LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}" fi CPPFLAGS="-I/usr/local/include ${saved_CPPFLAGS}" LIBS="$LIBS -lz" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBZ 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: *** zlib missing - please install first or check config.log ***" >&5 echo "$as_me: error: *** zlib missing - please install first or check config.log ***" >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi # Check whether --with-zlib-version-check was given. if test "${with_zlib_version_check+set}" = set; then withval=$with_zlib_version_check; if test "x$withval" = "xno" ; then zlib_check_nonfatal=1 fi fi { echo "$as_me:$LINENO: checking for possibly buggy zlib" >&5 echo $ECHO_N "checking for possibly buggy zlib... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking zlib version" >&5 echo "$as_me: WARNING: cross compiling: not checking zlib version" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { int a=0, b=0, c=0, d=0, n, v; n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d); if (n != 3 && n != 4) exit(1); v = a*1000000 + b*10000 + c*100 + d; fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v); /* 1.1.4 is OK */ if (a == 1 && b == 1 && c >= 4) exit(0); /* 1.2.3 and up are OK */ if (v >= 1020300) exit(0); exit(2); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } if test -z "$zlib_check_nonfatal" ; then { { echo "$as_me:$LINENO: error: *** zlib too old - check config.log *** Your reported zlib version has known security problems. It's possible your vendor has fixed these problems without changing the version number. If you are sure this is the case, you can disable the check by running \"./configure --without-zlib-version-check\". If you are in doubt, upgrade zlib to version 1.2.3 or greater. See http://www.gzip.org/zlib/ for details." >&5 echo "$as_me: error: *** zlib too old - check config.log *** Your reported zlib version has known security problems. It's possible your vendor has fixed these problems without changing the version number. If you are sure this is the case, you can disable the check by running \"./configure --without-zlib-version-check\". If you are in doubt, upgrade zlib to version 1.2.3 or greater. See http://www.gzip.org/zlib/ for details." >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: WARNING: zlib version may have security problems" >&5 echo "$as_me: WARNING: zlib version may have security problems" >&2;} fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking for strcasecmp" >&5 echo $ECHO_N "checking for strcasecmp... $ECHO_C" >&6; } if test "${ac_cv_func_strcasecmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define strcasecmp to an innocuous variant, in case declares strcasecmp. For example, HP-UX 11i declares gettimeofday. */ #define strcasecmp innocuous_strcasecmp /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strcasecmp (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef strcasecmp /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strcasecmp (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_strcasecmp || defined __stub___strcasecmp choke me #endif int main () { return strcasecmp (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_strcasecmp=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_strcasecmp=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_strcasecmp" >&5 echo "${ECHO_T}$ac_cv_func_strcasecmp" >&6; } if test $ac_cv_func_strcasecmp = yes; then : else { echo "$as_me:$LINENO: checking for strcasecmp in -lresolv" >&5 echo $ECHO_N "checking for strcasecmp in -lresolv... $ECHO_C" >&6; } if test "${ac_cv_lib_resolv_strcasecmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strcasecmp (); int main () { return strcasecmp (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_resolv_strcasecmp=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_strcasecmp=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_strcasecmp" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_strcasecmp" >&6; } if test $ac_cv_lib_resolv_strcasecmp = yes; then LIBS="$LIBS -lresolv" fi fi for ac_func in utimes do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else { echo "$as_me:$LINENO: checking for utimes in -lc89" >&5 echo $ECHO_N "checking for utimes in -lc89... $ECHO_C" >&6; } if test "${ac_cv_lib_c89_utimes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc89 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char utimes (); int main () { return utimes (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_c89_utimes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c89_utimes=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_c89_utimes" >&5 echo "${ECHO_T}$ac_cv_lib_c89_utimes" >&6; } if test $ac_cv_lib_c89_utimes = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UTIMES 1 _ACEOF LIBS="$LIBS -lc89" fi fi done for ac_header in bsd/libutil.h libutil.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for library containing fmt_scaled" >&5 echo $ECHO_N "checking for library containing fmt_scaled... $ECHO_C" >&6; } if test "${ac_cv_search_fmt_scaled+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fmt_scaled (); int main () { return fmt_scaled (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_fmt_scaled=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_fmt_scaled+set}" = set; then break fi done if test "${ac_cv_search_fmt_scaled+set}" = set; then : else ac_cv_search_fmt_scaled=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_fmt_scaled" >&5 echo "${ECHO_T}$ac_cv_search_fmt_scaled" >&6; } ac_res=$ac_cv_search_fmt_scaled if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing scan_scaled" >&5 echo $ECHO_N "checking for library containing scan_scaled... $ECHO_C" >&6; } if test "${ac_cv_search_scan_scaled+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char scan_scaled (); int main () { return scan_scaled (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_scan_scaled=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_scan_scaled+set}" = set; then break fi done if test "${ac_cv_search_scan_scaled+set}" = set; then : else ac_cv_search_scan_scaled=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_scan_scaled" >&5 echo "${ECHO_T}$ac_cv_search_scan_scaled" >&6; } ac_res=$ac_cv_search_scan_scaled if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing login" >&5 echo $ECHO_N "checking for library containing login... $ECHO_C" >&6; } if test "${ac_cv_search_login+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char login (); int main () { return login (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_login=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_login+set}" = set; then break fi done if test "${ac_cv_search_login+set}" = set; then : else ac_cv_search_login=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_login" >&5 echo "${ECHO_T}$ac_cv_search_login" >&6; } ac_res=$ac_cv_search_login if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing logout" >&5 echo $ECHO_N "checking for library containing logout... $ECHO_C" >&6; } if test "${ac_cv_search_logout+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char logout (); int main () { return logout (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_logout=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_logout+set}" = set; then break fi done if test "${ac_cv_search_logout+set}" = set; then : else ac_cv_search_logout=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_logout" >&5 echo "${ECHO_T}$ac_cv_search_logout" >&6; } ac_res=$ac_cv_search_logout if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing logwtmp" >&5 echo $ECHO_N "checking for library containing logwtmp... $ECHO_C" >&6; } if test "${ac_cv_search_logwtmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char logwtmp (); int main () { return logwtmp (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_logwtmp=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_logwtmp+set}" = set; then break fi done if test "${ac_cv_search_logwtmp+set}" = set; then : else ac_cv_search_logwtmp=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_logwtmp" >&5 echo "${ECHO_T}$ac_cv_search_logwtmp" >&6; } ac_res=$ac_cv_search_logwtmp if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing openpty" >&5 echo $ECHO_N "checking for library containing openpty... $ECHO_C" >&6; } if test "${ac_cv_search_openpty+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_openpty=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_openpty+set}" = set; then break fi done if test "${ac_cv_search_openpty+set}" = set; then : else ac_cv_search_openpty=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_openpty" >&5 echo "${ECHO_T}$ac_cv_search_openpty" >&6; } ac_res=$ac_cv_search_openpty if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing updwtmp" >&5 echo $ECHO_N "checking for library containing updwtmp... $ECHO_C" >&6; } if test "${ac_cv_search_updwtmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char updwtmp (); int main () { return updwtmp (); ; return 0; } _ACEOF for ac_lib in '' util bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_updwtmp=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_updwtmp+set}" = set; then break fi done if test "${ac_cv_search_updwtmp+set}" = set; then : else ac_cv_search_updwtmp=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_updwtmp" >&5 echo "${ECHO_T}$ac_cv_search_updwtmp" >&6; } ac_res=$ac_cv_search_updwtmp if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in fmt_scaled scan_scaled login logout openpty updwtmp logwtmp do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # On some platforms, inet_ntop and gethostbyname may be found in libresolv # or libnsl. { echo "$as_me:$LINENO: checking for library containing inet_ntop" >&5 echo $ECHO_N "checking for library containing inet_ntop... $ECHO_C" >&6; } if test "${ac_cv_search_inet_ntop+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntop (); int main () { return inet_ntop (); ; return 0; } _ACEOF for ac_lib in '' resolv nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_inet_ntop=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_inet_ntop+set}" = set; then break fi done if test "${ac_cv_search_inet_ntop+set}" = set; then : else ac_cv_search_inet_ntop=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_inet_ntop" >&5 echo "${ECHO_T}$ac_cv_search_inet_ntop" >&6; } ac_res=$ac_cv_search_inet_ntop if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6; } if test "${ac_cv_search_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF for ac_lib in '' resolv nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_gethostbyname=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_gethostbyname+set}" = set; then break fi done if test "${ac_cv_search_gethostbyname+set}" = set; then : else ac_cv_search_gethostbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6; } ac_res=$ac_cv_search_gethostbyname if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in strftime do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else # strftime is in -lintl on SCO UNIX. { echo "$as_me:$LINENO: checking for strftime in -lintl" >&5 echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6; } if test "${ac_cv_lib_intl_strftime+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strftime (); int main () { return strftime (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_intl_strftime=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_intl_strftime=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5 echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6; } if test $ac_cv_lib_intl_strftime = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRFTIME 1 _ACEOF LIBS="-lintl $LIBS" fi fi done # Check for ALTDIRFUNC glob() extension { echo "$as_me:$LINENO: checking for GLOB_ALTDIRFUNC support" >&5 echo $ECHO_N "checking for GLOB_ALTDIRFUNC support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef GLOB_ALTDIRFUNC FOUNDIT #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "FOUNDIT" >/dev/null 2>&1; then cat >>confdefs.h <<\_ACEOF #define GLOB_HAS_ALTDIRFUNC 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f conftest* # Check for g.gl_matchc glob() extension { echo "$as_me:$LINENO: checking for gl_matchc field in glob_t" >&5 echo $ECHO_N "checking for gl_matchc field in glob_t... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { glob_t g; g.gl_matchc = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define GLOB_HAS_GL_MATCHC 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Check for g.gl_statv glob() extension { echo "$as_me:$LINENO: checking for gl_statv and GLOB_KEEPSTAT extensions for glob" >&5 echo $ECHO_N "checking for gl_statv and GLOB_KEEPSTAT extensions for glob... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef GLOB_KEEPSTAT #error "glob does not support GLOB_KEEPSTAT extension" #endif glob_t g; g.gl_statv = NULL; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define GLOB_HAS_GL_STATV 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: checking whether GLOB_NOMATCH is declared" >&5 echo $ECHO_N "checking whether GLOB_NOMATCH is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_GLOB_NOMATCH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef GLOB_NOMATCH (void) GLOB_NOMATCH; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_GLOB_NOMATCH=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_GLOB_NOMATCH=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_GLOB_NOMATCH" >&5 echo "${ECHO_T}$ac_cv_have_decl_GLOB_NOMATCH" >&6; } if test $ac_cv_have_decl_GLOB_NOMATCH = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GLOB_NOMATCH 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GLOB_NOMATCH 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether struct dirent allocates space for d_name" >&5 echo $ECHO_N "checking whether struct dirent allocates space for d_name... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&5 echo "$as_me: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&2;} cat >>confdefs.h <<\_ACEOF #define BROKEN_ONE_BYTE_DIRENT_D_NAME 1 _ACEOF else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent d; exit(sizeof(d.d_name)<=sizeof(char)); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_ONE_BYTE_DIRENT_D_NAME 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking for /proc/pid/fd directory" >&5 echo $ECHO_N "checking for /proc/pid/fd directory... $ECHO_C" >&6; } if test -d "/proc/$$/fd" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_PROC_PID 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Check whether user wants S/Key support SKEY_MSG="no" # Check whether --with-skey was given. if test "${with_skey+set}" = set; then withval=$with_skey; if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" fi cat >>confdefs.h <<\_ACEOF #define SKEY 1 _ACEOF LIBS="-lskey $LIBS" SKEY_MSG="yes" { echo "$as_me:$LINENO: checking for s/key support" >&5 echo $ECHO_N "checking for s/key support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { char *ff = skey_keyinfo(""); ff=""; exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: ** Incomplete or missing s/key libraries." >&5 echo "$as_me: error: ** Incomplete or missing s/key libraries." >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking if skeychallenge takes 4 arguments" >&5 echo $ECHO_N "checking if skeychallenge takes 4 arguments... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { (void)skeychallenge(NULL,"name","",0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define SKEYCHALLENGE_4ARG 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi # Check whether user wants to use ldns LDNS_MSG="no" # Check whether --with-ldns was given. if test "${with_ldns+set}" = set; then withval=$with_ldns; if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" fi cat >>confdefs.h <<\_ACEOF #define HAVE_LDNS 1 _ACEOF LIBS="-lldns $LIBS" LDNS_MSG="yes" { echo "$as_me:$LINENO: checking for ldns support" >&5 echo $ECHO_N "checking for ldns support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: ** Incomplete or missing ldns libraries." >&5 echo "$as_me: error: ** Incomplete or missing ldns libraries." >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi fi # Check whether user wants libedit support LIBEDIT_MSG="no" # Check whether --with-libedit was given. if test "${with_libedit+set}" = set; then withval=$with_libedit; if test "x$withval" != "xno" ; then if test "x$withval" = "xyes" ; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKGCONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKGCONFIG=$ac_cv_path_PKGCONFIG if test -n "$PKGCONFIG"; then { echo "$as_me:$LINENO: result: $PKGCONFIG" >&5 echo "${ECHO_T}$PKGCONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_path_PKGCONFIG"; then ac_pt_PKGCONFIG=$PKGCONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_ac_pt_PKGCONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $ac_pt_PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG if test -n "$ac_pt_PKGCONFIG"; then { echo "$as_me:$LINENO: result: $ac_pt_PKGCONFIG" >&5 echo "${ECHO_T}$ac_pt_PKGCONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_pt_PKGCONFIG" = x; then PKGCONFIG="no" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac PKGCONFIG=$ac_pt_PKGCONFIG fi else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi if test "x$PKGCONFIG" != "xno"; then { echo "$as_me:$LINENO: checking if $PKGCONFIG knows about libedit" >&5 echo $ECHO_N "checking if $PKGCONFIG knows about libedit... $ECHO_C" >&6; } if "$PKGCONFIG" libedit; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } use_pkgconfig_for_libedit=yes else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi else CPPFLAGS="$CPPFLAGS -I${withval}/include" if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi fi if test "x$use_pkgconfig_for_libedit" = "xyes"; then LIBEDIT=`$PKGCONFIG --libs libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else LIBEDIT="-ledit -lcurses" fi OTHERLIBS=`echo $LIBEDIT | sed 's/-ledit//'` { echo "$as_me:$LINENO: checking for el_init in -ledit" >&5 echo $ECHO_N "checking for el_init in -ledit... $ECHO_C" >&6; } if test "${ac_cv_lib_edit_el_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ledit $OTHERLIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char el_init (); int main () { return el_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_edit_el_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_edit_el_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_edit_el_init" >&5 echo "${ECHO_T}$ac_cv_lib_edit_el_init" >&6; } if test $ac_cv_lib_edit_el_init = yes; then cat >>confdefs.h <<\_ACEOF #define USE_LIBEDIT 1 _ACEOF LIBEDIT_MSG="yes" else { { echo "$as_me:$LINENO: error: libedit not found" >&5 echo "$as_me: error: libedit not found" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking if libedit version is compatible" >&5 echo $ECHO_N "checking if libedit version is compatible... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { int i = H_SETSIZE; el_init("", NULL, NULL, NULL); exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: libedit version is not compatible" >&5 echo "$as_me: error: libedit version is not compatible" >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi AUDIT_MODULE=none # Check whether --with-audit was given. if test "${with_audit+set}" = set; then withval=$with_audit; { echo "$as_me:$LINENO: checking for supported audit module" >&5 echo $ECHO_N "checking for supported audit module... $ECHO_C" >&6; } case "$withval" in bsm) { echo "$as_me:$LINENO: result: bsm" >&5 echo "${ECHO_T}bsm" >&6; } AUDIT_MODULE=bsm for ac_header in bsm/audit.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_TIME_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else { { echo "$as_me:$LINENO: error: BSM enabled and bsm/audit.h not found" >&5 echo "$as_me: error: BSM enabled and bsm/audit.h not found" >&2;} { (exit 1); exit 1; }; } fi done { echo "$as_me:$LINENO: checking for getaudit in -lbsm" >&5 echo $ECHO_N "checking for getaudit in -lbsm... $ECHO_C" >&6; } if test "${ac_cv_lib_bsm_getaudit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getaudit (); int main () { return getaudit (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_bsm_getaudit=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsm_getaudit=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bsm_getaudit" >&5 echo "${ECHO_T}$ac_cv_lib_bsm_getaudit" >&6; } if test $ac_cv_lib_bsm_getaudit = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBBSM 1 _ACEOF LIBS="-lbsm $LIBS" else { { echo "$as_me:$LINENO: error: BSM enabled and required library not found" >&5 echo "$as_me: error: BSM enabled and required library not found" >&2;} { (exit 1); exit 1; }; } fi for ac_func in getaudit do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else { { echo "$as_me:$LINENO: error: BSM enabled and required function not found" >&5 echo "$as_me: error: BSM enabled and required function not found" >&2;} { (exit 1); exit 1; }; } fi done # These are optional for ac_func in getaudit_addr aug_get_machine do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done cat >>confdefs.h <<\_ACEOF #define USE_BSM_AUDIT 1 _ACEOF if test "$sol2ver" -ge 11; then SSHDLIBS="$SSHDLIBS -lscf" cat >>confdefs.h <<\_ACEOF #define BROKEN_BSM_API 1 _ACEOF fi ;; linux) { echo "$as_me:$LINENO: result: linux" >&5 echo "${ECHO_T}linux" >&6; } AUDIT_MODULE=linux for ac_header in libaudit.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done SSHDLIBS="$SSHDLIBS -laudit" cat >>confdefs.h <<\_ACEOF #define USE_LINUX_AUDIT 1 _ACEOF ;; debug) AUDIT_MODULE=debug { echo "$as_me:$LINENO: result: debug" >&5 echo "${ECHO_T}debug" >&6; } cat >>confdefs.h <<\_ACEOF #define SSH_AUDIT_EVENTS 1 _ACEOF ;; no) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } ;; *) { { echo "$as_me:$LINENO: error: Unknown audit module $withval" >&5 echo "$as_me: error: Unknown audit module $withval" >&2;} { (exit 1); exit 1; }; } ;; esac fi # Check whether --with-pie was given. if test "${with_pie+set}" = set; then withval=$with_pie; if test "x$withval" = "xno"; then use_pie=no fi if test "x$withval" = "xyes"; then use_pie=yes fi fi if test "x$use_pie" = "x"; then use_pie=no fi if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then # Turn off automatic PIE when toolchain hardening is off. use_pie=no fi if test "x$use_pie" = "xauto"; then # Automatic PIE requires gcc >= 4.x { echo "$as_me:$LINENO: checking for gcc >= 4.x" >&5 echo $ECHO_N "checking for gcc >= 4.x... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if !defined(__GNUC__) || __GNUC__ < 4 #error gcc is too old #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } use_pie=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x$use_pie" != "xno"; then SAVED_CFLAGS="$CFLAGS" SAVED_LDFLAGS="$LDFLAGS" { { echo "$as_me:$LINENO: checking if $CC supports compile flag -fPIE" >&5 echo $ECHO_N "checking if $CC supports compile flag -fPIE... $ECHO_C" >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fPIE" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-fPIE" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if `grep -i "unrecognized option" conftest.err >/dev/null` then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" else { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { echo "$as_me:$LINENO: checking if $LD supports link flag -pie" >&5 echo $ECHO_N "checking if $LD supports link flag -pie... $ECHO_C" >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -pie" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-pie" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main(int argc, char **argv) { /* Some math to catch -ftrapv problems in the toolchain */ int i = 123 * argc, j = 456 + argc, k = 789 - argc; float l = i * 2.1; double m = l / 0.5; long long int n = argc * 12345LL, o = 12345LL * (long long int)argc; printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o); exit(0); } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext } # We use both -fPIE and -pie or neither. { echo "$as_me:$LINENO: checking whether both -fPIE and -pie are supported" >&5 echo $ECHO_N "checking whether both -fPIE and -pie are supported... $ECHO_C" >&6; } if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \ echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } CFLAGS="$SAVED_CFLAGS" LDFLAGS="$SAVED_LDFLAGS" fi fi for ac_func in \ Blowfish_initstate \ Blowfish_expandstate \ Blowfish_expand0state \ Blowfish_stream2word \ asprintf \ b64_ntop \ __b64_ntop \ b64_pton \ __b64_pton \ bcopy \ bcrypt_pbkdf \ bindresvport_sa \ blf_enc \ cap_rights_limit \ clock \ closefrom \ dirfd \ endgrent \ explicit_bzero \ fchmod \ fchown \ freeaddrinfo \ fstatfs \ fstatvfs \ futimes \ getaddrinfo \ getcwd \ getgrouplist \ getnameinfo \ getopt \ getpeereid \ getpeerucred \ getpgid \ getpgrp \ _getpty \ getrlimit \ getttyent \ glob \ group_from_gid \ inet_aton \ inet_ntoa \ inet_ntop \ innetgr \ login_getcapbool \ mblen \ md5_crypt \ memmove \ memset_s \ mkdtemp \ mmap \ ngetaddrinfo \ nsleep \ ogetaddrinfo \ openlog_r \ pledge \ poll \ prctl \ pstat \ readpassphrase \ reallocarray \ recvmsg \ rresvport_af \ sendmsg \ setdtablesize \ setegid \ setenv \ seteuid \ setgroupent \ setgroups \ setlinebuf \ setlogin \ setpassent\ setpcred \ setproctitle \ setregid \ setreuid \ setrlimit \ setsid \ setvbuf \ sigaction \ sigvec \ snprintf \ socketpair \ statfs \ statvfs \ strdup \ strerror \ strlcat \ strlcpy \ strmode \ strnlen \ strnvis \ strptime \ strtonum \ strtoll \ strtoul \ strtoull \ swap32 \ sysconf \ tcgetpgrp \ timingsafe_bcmp \ truncate \ unsetenv \ updwtmpx \ user_from_uid \ usleep \ vasprintf \ vsnprintf \ waitpid \ do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { return (isblank('a')); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_ISBLANK 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # PKCS11 depends on OpenSSL. if test "x$openssl" = "xyes" ; then # PKCS#11 support requires dlopen() and co { echo "$as_me:$LINENO: checking for library containing dlopen" >&5 echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6; } if test "${ac_cv_search_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break fi done if test "${ac_cv_search_dlopen+set}" = set; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5 echo "${ECHO_T}$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define ENABLE_PKCS11 _ACEOF fi fi # IRIX has a const char return value for gai_strerror() for ac_func in gai_strerror do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_GAI_STRERROR 1 _ACEOF cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include const char *gai_strerror(int); int main () { char *str; str = gai_strerror(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_CONST_GAI_STRERROR_PROTO 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi done { echo "$as_me:$LINENO: checking for library containing nanosleep" >&5 echo $ECHO_N "checking for library containing nanosleep... $ECHO_C" >&6; } if test "${ac_cv_search_nanosleep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF for ac_lib in '' rt posix4; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_nanosleep=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_nanosleep+set}" = set; then break fi done if test "${ac_cv_search_nanosleep+set}" = set; then : else ac_cv_search_nanosleep=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_nanosleep" >&5 echo "${ECHO_T}$ac_cv_search_nanosleep" >&6; } ac_res=$ac_cv_search_nanosleep if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_NANOSLEEP 1 _ACEOF fi { echo "$as_me:$LINENO: checking for library containing clock_gettime" >&5 echo $ECHO_N "checking for library containing clock_gettime... $ECHO_C" >&6; } if test "${ac_cv_search_clock_gettime+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_clock_gettime=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_clock_gettime+set}" = set; then break fi done if test "${ac_cv_search_clock_gettime+set}" = set; then : else ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_clock_gettime" >&5 echo "${ECHO_T}$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether getrusage is declared" >&5 echo $ECHO_N "checking whether getrusage is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_getrusage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef getrusage (void) getrusage; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_getrusage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_getrusage=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_getrusage" >&5 echo "${ECHO_T}$ac_cv_have_decl_getrusage" >&6; } if test $ac_cv_have_decl_getrusage = yes; then for ac_func in getrusage do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi { echo "$as_me:$LINENO: checking whether strsep is declared" >&5 echo $ECHO_N "checking whether strsep is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_strsep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STRING_H # include #endif int main () { #ifndef strsep (void) strsep; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_strsep=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strsep=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_strsep" >&5 echo "${ECHO_T}$ac_cv_have_decl_strsep" >&6; } if test $ac_cv_have_decl_strsep = yes; then for ac_func in strsep do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi { echo "$as_me:$LINENO: checking whether tcsendbreak is declared" >&5 echo $ECHO_N "checking whether tcsendbreak is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_tcsendbreak+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef tcsendbreak (void) tcsendbreak; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_tcsendbreak=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_tcsendbreak=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_tcsendbreak" >&5 echo "${ECHO_T}$ac_cv_have_decl_tcsendbreak" >&6; } if test $ac_cv_have_decl_tcsendbreak = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_TCSENDBREAK 1 _ACEOF else for ac_func in tcsendbreak do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi { echo "$as_me:$LINENO: checking whether h_errno is declared" >&5 echo $ECHO_N "checking whether h_errno is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_h_errno+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef h_errno (void) h_errno; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_h_errno=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_h_errno=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_h_errno" >&5 echo "${ECHO_T}$ac_cv_have_decl_h_errno" >&6; } if test $ac_cv_have_decl_h_errno = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_H_ERRNO 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_H_ERRNO 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether SHUT_RD is declared" >&5 echo $ECHO_N "checking whether SHUT_RD is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_SHUT_RD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef SHUT_RD (void) SHUT_RD; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_SHUT_RD=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_SHUT_RD=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_SHUT_RD" >&5 echo "${ECHO_T}$ac_cv_have_decl_SHUT_RD" >&6; } if test $ac_cv_have_decl_SHUT_RD = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SHUT_RD 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SHUT_RD 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether O_NONBLOCK is declared" >&5 echo $ECHO_N "checking whether O_NONBLOCK is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_O_NONBLOCK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif int main () { #ifndef O_NONBLOCK (void) O_NONBLOCK; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_O_NONBLOCK=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_O_NONBLOCK=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_O_NONBLOCK" >&5 echo "${ECHO_T}$ac_cv_have_decl_O_NONBLOCK" >&6; } if test $ac_cv_have_decl_O_NONBLOCK = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_O_NONBLOCK 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_O_NONBLOCK 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether writev is declared" >&5 echo $ECHO_N "checking whether writev is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_writev+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { #ifndef writev (void) writev; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_writev=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_writev=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_writev" >&5 echo "${ECHO_T}$ac_cv_have_decl_writev" >&6; } if test $ac_cv_have_decl_writev = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_WRITEV 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_WRITEV 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether MAXSYMLINKS is declared" >&5 echo $ECHO_N "checking whether MAXSYMLINKS is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_MAXSYMLINKS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef MAXSYMLINKS (void) MAXSYMLINKS; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_MAXSYMLINKS=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_MAXSYMLINKS=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_MAXSYMLINKS" >&5 echo "${ECHO_T}$ac_cv_have_decl_MAXSYMLINKS" >&6; } if test $ac_cv_have_decl_MAXSYMLINKS = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MAXSYMLINKS 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MAXSYMLINKS 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether offsetof is declared" >&5 echo $ECHO_N "checking whether offsetof is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_offsetof+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef offsetof (void) offsetof; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_offsetof=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_offsetof=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_offsetof" >&5 echo "${ECHO_T}$ac_cv_have_decl_offsetof" >&6; } if test $ac_cv_have_decl_offsetof = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_OFFSETOF 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_OFFSETOF 0 _ACEOF fi # extra bits for select(2) { echo "$as_me:$LINENO: checking whether howmany is declared" >&5 echo $ECHO_N "checking whether howmany is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_howmany+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_SYS_SYSMACROS_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif int main () { #ifndef howmany (void) howmany; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_howmany=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_howmany=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_howmany" >&5 echo "${ECHO_T}$ac_cv_have_decl_howmany" >&6; } if test $ac_cv_have_decl_howmany = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_HOWMANY 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_HOWMANY 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether NFDBITS is declared" >&5 echo $ECHO_N "checking whether NFDBITS is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_NFDBITS+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_SYS_SYSMACROS_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif int main () { #ifndef NFDBITS (void) NFDBITS; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_NFDBITS=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_NFDBITS=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_NFDBITS" >&5 echo "${ECHO_T}$ac_cv_have_decl_NFDBITS" >&6; } if test $ac_cv_have_decl_NFDBITS = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_NFDBITS 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_NFDBITS 0 _ACEOF fi { echo "$as_me:$LINENO: checking for fd_mask" >&5 echo $ECHO_N "checking for fd_mask... $ECHO_C" >&6; } if test "${ac_cv_type_fd_mask+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif typedef fd_mask ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_fd_mask=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_fd_mask=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_fd_mask" >&5 echo "${ECHO_T}$ac_cv_type_fd_mask" >&6; } if test $ac_cv_type_fd_mask = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_FD_MASK 1 _ACEOF fi for ac_func in setresuid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { echo "$as_me:$LINENO: checking if setresuid seems to work" >&5 echo $ECHO_N "checking if setresuid seems to work... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking setresuid" >&5 echo "$as_me: WARNING: cross compiling: not checking setresuid" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) cat >>confdefs.h <<\_ACEOF #define BROKEN_SETRESUID 1 _ACEOF { echo "$as_me:$LINENO: result: not implemented" >&5 echo "${ECHO_T}not implemented" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi done for ac_func in setresgid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { echo "$as_me:$LINENO: checking if setresgid seems to work" >&5 echo $ECHO_N "checking if setresgid seems to work... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking setresuid" >&5 echo "$as_me: WARNING: cross compiling: not checking setresuid" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) cat >>confdefs.h <<\_ACEOF #define BROKEN_SETRESGID 1 _ACEOF { echo "$as_me:$LINENO: result: not implemented" >&5 echo "${ECHO_T}not implemented" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi done for ac_func in realpath do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { echo "$as_me:$LINENO: checking if realpath works with non-existent files" >&5 echo $ECHO_N "checking if realpath works with non-existent files... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming working" >&5 echo "$as_me: WARNING: cross compiling: assuming working" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { char buf[PATH_MAX]; if (realpath("/opensshnonexistentfilename1234", buf) == NULL) if (errno == ENOENT) exit(1); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) cat >>confdefs.h <<\_ACEOF #define BROKEN_REALPATH 1 _ACEOF { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi done for ac_func in gettimeofday time do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in endutent getutent getutid getutline pututline setutent do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in utmpname do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in endutxent getutxent getutxid getutxline getutxuser pututxline do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setutxdb setutxent utmpxname do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getlastlogxbyname do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for daemon" >&5 echo $ECHO_N "checking for daemon... $ECHO_C" >&6; } if test "${ac_cv_func_daemon+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define daemon to an innocuous variant, in case declares daemon. For example, HP-UX 11i declares gettimeofday. */ #define daemon innocuous_daemon /* System header to define __stub macros and hopefully few prototypes, which can conflict with char daemon (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef daemon /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char daemon (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_daemon || defined __stub___daemon choke me #endif int main () { return daemon (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_daemon=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_daemon=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_daemon" >&5 echo "${ECHO_T}$ac_cv_func_daemon" >&6; } if test $ac_cv_func_daemon = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DAEMON 1 _ACEOF else { echo "$as_me:$LINENO: checking for daemon in -lbsd" >&5 echo $ECHO_N "checking for daemon in -lbsd... $ECHO_C" >&6; } if test "${ac_cv_lib_bsd_daemon+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char daemon (); int main () { return daemon (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_bsd_daemon=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_daemon=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_daemon" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_daemon" >&6; } if test $ac_cv_lib_bsd_daemon = yes; then LIBS="$LIBS -lbsd"; cat >>confdefs.h <<\_ACEOF #define HAVE_DAEMON 1 _ACEOF fi fi { echo "$as_me:$LINENO: checking for getpagesize" >&5 echo $ECHO_N "checking for getpagesize... $ECHO_C" >&6; } if test "${ac_cv_func_getpagesize+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define getpagesize to an innocuous variant, in case declares getpagesize. For example, HP-UX 11i declares gettimeofday. */ #define getpagesize innocuous_getpagesize /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpagesize (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef getpagesize /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getpagesize (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_getpagesize || defined __stub___getpagesize choke me #endif int main () { return getpagesize (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_getpagesize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_getpagesize=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_getpagesize" >&5 echo "${ECHO_T}$ac_cv_func_getpagesize" >&6; } if test $ac_cv_func_getpagesize = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF else { echo "$as_me:$LINENO: checking for getpagesize in -lucb" >&5 echo $ECHO_N "checking for getpagesize in -lucb... $ECHO_C" >&6; } if test "${ac_cv_lib_ucb_getpagesize+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lucb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getpagesize (); int main () { return getpagesize (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ucb_getpagesize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ucb_getpagesize=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ucb_getpagesize" >&5 echo "${ECHO_T}$ac_cv_lib_ucb_getpagesize" >&6; } if test $ac_cv_lib_ucb_getpagesize = yes; then LIBS="$LIBS -lucb"; cat >>confdefs.h <<\_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi fi # Check for broken snprintf if test "x$ac_cv_func_snprintf" = "xyes" ; then { echo "$as_me:$LINENO: checking whether snprintf correctly terminates long strings" >&5 echo $ECHO_N "checking whether snprintf correctly terminates long strings... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: Assuming working snprintf()" >&5 echo "$as_me: WARNING: cross compiling: Assuming working snprintf()" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char b[5]; snprintf(b,5,"123456789"); exit(b[4]!='\0'); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_SNPRINTF 1 _ACEOF { echo "$as_me:$LINENO: WARNING: ****** Your snprintf() function is broken, complain to your vendor" >&5 echo "$as_me: WARNING: ****** Your snprintf() function is broken, complain to your vendor" >&2;} fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi # We depend on vsnprintf returning the right thing on overflow: the # number of characters it tried to create (as per SUSv3) if test "x$ac_cv_func_vsnprintf" = "xyes" ; then { echo "$as_me:$LINENO: checking whether vsnprintf returns correct values on overflow" >&5 echo $ECHO_N "checking whether vsnprintf returns correct values on overflow... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: Assuming working vsnprintf()" >&5 echo "$as_me: WARNING: cross compiling: Assuming working vsnprintf()" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int x_snprintf(char *str, size_t count, const char *fmt, ...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } int main () { char x[1]; if (x_snprintf(x, 1, "%s %d", "hello", 12345) != 11) return 1; if (x_snprintf(NULL, 0, "%s %d", "hello", 12345) != 11) return 1; return 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_SNPRINTF 1 _ACEOF { echo "$as_me:$LINENO: WARNING: ****** Your vsnprintf() function is broken, complain to your vendor" >&5 echo "$as_me: WARNING: ****** Your vsnprintf() function is broken, complain to your vendor" >&2;} fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi # On systems where [v]snprintf is broken, but is declared in stdio, # check that the fmt argument is const char * or just char *. # This is only useful for when BROKEN_SNPRINTF { echo "$as_me:$LINENO: checking whether snprintf can declare const char *fmt" >&5 echo $ECHO_N "checking whether snprintf can declare const char *fmt... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } int main () { snprintf(0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define SNPRINTF_CONST const _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define SNPRINTF_CONST /* not const */ _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Check for missing getpeereid (or equiv) support NO_PEERCHECK="" if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then { echo "$as_me:$LINENO: checking whether system supports SO_PEERCRED getsockopt" >&5 echo $ECHO_N "checking whether system supports SO_PEERCRED getsockopt... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { int i = SO_PEERCRED; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_SO_PEERCRED 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } NO_PEERCHECK=1 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x$ac_cv_func_mkdtemp" = "xyes" ; then { echo "$as_me:$LINENO: checking for (overly) strict mkstemp" >&5 echo $ECHO_N "checking for (overly) strict mkstemp... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_STRICT_MKSTEMP 1 _ACEOF else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char template[]="conftest.mkstemp-test"; if (mkstemp(template) == -1) exit(1); unlink(template); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_STRICT_MKSTEMP 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi if test ! -z "$check_for_openpty_ctty_bug"; then { echo "$as_me:$LINENO: checking if openpty correctly handles controlling tty" >&5 echo $ECHO_N "checking if openpty correctly handles controlling tty... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: cross-compiling, assuming yes" >&5 echo "${ECHO_T}cross-compiling, assuming yes" >&6; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { pid_t pid; int fd, ptyfd, ttyfd, status; pid = fork(); if (pid < 0) { /* failed */ exit(1); } else if (pid > 0) { /* parent */ waitpid(pid, &status, 0); if (WIFEXITED(status)) exit(WEXITSTATUS(status)); else exit(2); } else { /* child */ close(0); close(1); close(2); setsid(); openpty(&ptyfd, &ttyfd, NULL, NULL, NULL); fd = open("/dev/tty", O_RDWR | O_NOCTTY); if (fd >= 0) exit(3); /* Acquired ctty: broken */ else exit(0); /* Did not acquire ctty: OK */ } ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define SSHD_ACQUIRES_CTTY 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then { echo "$as_me:$LINENO: checking if getaddrinfo seems to work" >&5 echo $ECHO_N "checking if getaddrinfo seems to work... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: cross-compiling, assuming yes" >&5 echo "${ECHO_T}cross-compiling, assuming yes" >&6; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #define TEST_PORT "2222" int main () { int err, sock; struct addrinfo *gai_ai, *ai, hints; char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); if (err != 0) { fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); exit(1); } for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET6) continue; err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV); if (err != 0) { if (err == EAI_SYSTEM) perror("getnameinfo EAI_SYSTEM"); else fprintf(stderr, "getnameinfo failed: %s\n", gai_strerror(err)); exit(2); } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) perror("socket"); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { if (errno == EBADF) exit(3); } } exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_aix_broken_getaddrinfo" = "x1"; then { echo "$as_me:$LINENO: checking if getaddrinfo seems to work" >&5 echo $ECHO_N "checking if getaddrinfo seems to work... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: cross-compiling, assuming no" >&5 echo "${ECHO_T}cross-compiling, assuming no" >&6; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #define TEST_PORT "2222" int main () { int err, sock; struct addrinfo *gai_ai, *ai, hints; char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); if (err != 0) { fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); exit(1); } for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV); if (ai->ai_family == AF_INET && err != 0) { perror("getnameinfo"); exit(2); } } exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define AIX_GETNAMEINFO_HACK 1 _ACEOF else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define BROKEN_GETADDRINFO 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes"; then { echo "$as_me:$LINENO: checking whether AI_NUMERICSERV is declared" >&5 echo $ECHO_N "checking whether AI_NUMERICSERV is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_AI_NUMERICSERV+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { #ifndef AI_NUMERICSERV (void) AI_NUMERICSERV; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_AI_NUMERICSERV=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_AI_NUMERICSERV=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_AI_NUMERICSERV" >&5 echo "${ECHO_T}$ac_cv_have_decl_AI_NUMERICSERV" >&6; } if test $ac_cv_have_decl_AI_NUMERICSERV = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AI_NUMERICSERV 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AI_NUMERICSERV 0 _ACEOF fi fi if test "x$check_for_conflicting_getspnam" = "x1"; then { echo "$as_me:$LINENO: checking for conflicting getspnam in shadow.h" >&5 echo $ECHO_N "checking for conflicting getspnam in shadow.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define GETSPNAM_CONFLICTING_DEFS 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking whether getpgrp requires zero arguments" >&5 echo $ECHO_N "checking whether getpgrp requires zero arguments... $ECHO_C" >&6; } if test "${ac_cv_func_getpgrp_void+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use it with a single arg. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { getpgrp (0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_func_getpgrp_void=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_getpgrp_void=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_getpgrp_void" >&5 echo "${ECHO_T}$ac_cv_func_getpgrp_void" >&6; } if test $ac_cv_func_getpgrp_void = yes; then cat >>confdefs.h <<\_ACEOF #define GETPGRP_VOID 1 _ACEOF fi # Search for OpenSSL saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" # Check whether --with-ssl-dir was given. if test "${with_ssl_dir+set}" = set; then withval=$with_ssl_dir; if test "x$openssl" = "xno" ; then { { echo "$as_me:$LINENO: error: cannot use --with-ssl-dir when OpenSSL disabled" >&5 echo "$as_me: error: cannot use --with-ssl-dir when OpenSSL disabled" >&2;} { (exit 1); exit 1; }; } fi if test "x$withval" != "xno" ; then case "$withval" in # Relative paths ./*|../*) withval="`pwd`/$withval" esac if test -d "$withval/lib"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" else LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi elif test -d "$withval/lib64"; then if test -n "${need_dash_r}"; then LDFLAGS="-L${withval}/lib64 -R${withval}/lib64 ${LDFLAGS}" else LDFLAGS="-L${withval}/lib64 ${LDFLAGS}" fi else if test -n "${need_dash_r}"; then LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" else LDFLAGS="-L${withval} ${LDFLAGS}" fi fi if test -d "$withval/include"; then CPPFLAGS="-I${withval}/include ${CPPFLAGS}" else CPPFLAGS="-I${withval} ${CPPFLAGS}" fi fi fi # Check whether --with-openssl-header-check was given. if test "${with_openssl_header_check+set}" = set; then withval=$with_openssl_header_check; if test "x$withval" = "xno" ; then openssl_check_nonfatal=1 fi fi openssl_engine=no # Check whether --with-ssl-engine was given. if test "${with_ssl_engine+set}" = set; then withval=$with_ssl_engine; if test "x$withval" != "xno" ; then if test "x$openssl" = "xno" ; then { { echo "$as_me:$LINENO: error: cannot use --with-ssl-engine when OpenSSL disabled" >&5 echo "$as_me: error: cannot use --with-ssl-engine when OpenSSL disabled" >&2;} { (exit 1); exit 1; }; } fi openssl_engine=yes fi fi if test "x$openssl" = "xyes" ; then LIBS="-lcrypto $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char RAND_add (); int main () { return RAND_add (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_OPENSSL 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 if test -n "${need_dash_r}"; then LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" else LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" fi CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" if test "${ac_cv_header_openssl_opensslv_h+set}" = set; then { echo "$as_me:$LINENO: checking for openssl/opensslv.h" >&5 echo $ECHO_N "checking for openssl/opensslv.h... $ECHO_C" >&6; } if test "${ac_cv_header_openssl_opensslv_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_openssl_opensslv_h" >&5 echo "${ECHO_T}$ac_cv_header_openssl_opensslv_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking openssl/opensslv.h usability" >&5 echo $ECHO_N "checking openssl/opensslv.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking openssl/opensslv.h presence" >&5 echo $ECHO_N "checking openssl/opensslv.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: openssl/opensslv.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: openssl/opensslv.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: openssl/opensslv.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: openssl/opensslv.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: openssl/opensslv.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: openssl/opensslv.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: openssl/opensslv.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: openssl/opensslv.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: openssl/opensslv.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for openssl/opensslv.h" >&5 echo $ECHO_N "checking for openssl/opensslv.h... $ECHO_C" >&6; } if test "${ac_cv_header_openssl_opensslv_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_openssl_opensslv_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_openssl_opensslv_h" >&5 echo "${ECHO_T}$ac_cv_header_openssl_opensslv_h" >&6; } fi if test $ac_cv_header_openssl_opensslv_h = yes; then : else { { echo "$as_me:$LINENO: error: *** OpenSSL headers missing - please install first or check config.log ***" >&5 echo "$as_me: error: *** OpenSSL headers missing - please install first or check config.log ***" >&2;} { (exit 1); exit 1; }; } fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char RAND_add (); int main () { return RAND_add (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_OPENSSL 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: *** Can't find recent OpenSSL libcrypto (see config.log for details) ***" >&5 echo "$as_me: error: *** Can't find recent OpenSSL libcrypto (see config.log for details) ***" >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Determine OpenSSL header version { echo "$as_me:$LINENO: checking OpenSSL header version" >&5 echo $ECHO_N "checking OpenSSL header version... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking" >&5 echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #define DATA "conftest.sslincver" int main () { FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd ,"%08lx (%s)\n", (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) exit(1); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ssl_header_ver=`cat conftest.sslincver` { echo "$as_me:$LINENO: result: $ssl_header_ver" >&5 echo "${ECHO_T}$ssl_header_ver" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: OpenSSL version header not found." >&5 echo "$as_me: error: OpenSSL version header not found." >&2;} { (exit 1); exit 1; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi # Determine OpenSSL library version { echo "$as_me:$LINENO: checking OpenSSL library version" >&5 echo $ECHO_N "checking OpenSSL library version... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking" >&5 echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #define DATA "conftest.ssllibver" int main () { FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0) exit(1); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ssl_library_ver=`cat conftest.ssllibver` # Check version is supported. case "$ssl_library_ver" in 0090[0-7]*|009080[0-5]*) { { echo "$as_me:$LINENO: error: OpenSSL >= 0.9.8f required (have \"$ssl_library_ver\")" >&5 echo "$as_me: error: OpenSSL >= 0.9.8f required (have \"$ssl_library_ver\")" >&2;} { (exit 1); exit 1; }; } ;; *) ;; esac { echo "$as_me:$LINENO: result: $ssl_library_ver" >&5 echo "${ECHO_T}$ssl_library_ver" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } { { echo "$as_me:$LINENO: error: OpenSSL library not found." >&5 echo "$as_me: error: OpenSSL library not found." >&2;} { (exit 1); exit 1; }; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi # Sanity check OpenSSL headers { echo "$as_me:$LINENO: checking whether OpenSSL's headers match the library" >&5 echo $ECHO_N "checking whether OpenSSL's headers match the library... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking" >&5 echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } if test "x$openssl_check_nonfatal" = "x"; then { { echo "$as_me:$LINENO: error: Your OpenSSL headers do not match your library. Check config.log for details. If you are sure your installation is consistent, you can disable the check by running \"./configure --without-openssl-header-check\". Also see contrib/findssl.sh for help identifying header/library mismatches. " >&5 echo "$as_me: error: Your OpenSSL headers do not match your library. Check config.log for details. If you are sure your installation is consistent, you can disable the check by running \"./configure --without-openssl-header-check\". Also see contrib/findssl.sh for help identifying header/library mismatches. " >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: WARNING: Your OpenSSL headers do not match your library. Check config.log for details. Also see contrib/findssl.sh for help identifying header/library mismatches." >&5 echo "$as_me: WARNING: Your OpenSSL headers do not match your library. Check config.log for details. Also see contrib/findssl.sh for help identifying header/library mismatches." >&2;} fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking if programs using OpenSSL functions will link" >&5 echo $ECHO_N "checking if programs using OpenSSL functions will link... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { SSLeay_add_all_algorithms(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } saved_LIBS="$LIBS" LIBS="$LIBS -ldl" { echo "$as_me:$LINENO: checking if programs using OpenSSL need -ldl" >&5 echo $ECHO_N "checking if programs using OpenSSL need -ldl... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { SSLeay_add_all_algorithms(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } LIBS="$saved_LIBS" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext for ac_func in \ BN_is_prime_ex \ DSA_generate_parameters_ex \ EVP_DigestInit_ex \ EVP_DigestFinal_ex \ EVP_MD_CTX_init \ EVP_MD_CTX_cleanup \ EVP_MD_CTX_copy_ex \ HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$openssl_engine" = "xyes" ; then { echo "$as_me:$LINENO: checking for OpenSSL ENGINE support" >&5 echo $ECHO_N "checking for OpenSSL ENGINE support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define USE_OPENSSL_ENGINE 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: OpenSSL ENGINE support not found" >&5 echo "$as_me: error: OpenSSL ENGINE support not found" >&2;} { (exit 1); exit 1; }; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi # Check for OpenSSL without EVP_aes_{192,256}_cbc { echo "$as_me:$LINENO: checking whether OpenSSL has crippled AES support" >&5 echo $ECHO_N "checking whether OpenSSL has crippled AES support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define OPENSSL_LOBOTOMISED_AES 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Check for OpenSSL with EVP_aes_*ctr { echo "$as_me:$LINENO: checking whether OpenSSL has AES CTR via EVP" >&5 echo $ECHO_N "checking whether OpenSSL has AES CTR via EVP... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { exit(EVP_aes_128_ctr() == NULL || EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAVE_EVPCTR 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Check for OpenSSL with EVP_aes_*gcm { echo "$as_me:$LINENO: checking whether OpenSSL has AES GCM via EVP" >&5 echo $ECHO_N "checking whether OpenSSL has AES GCM via EVP... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { exit(EVP_aes_128_gcm() == NULL || EVP_aes_256_gcm() == NULL || EVP_CTRL_GCM_SET_IV_FIXED == 0 || EVP_CTRL_GCM_IV_GEN == 0 || EVP_CTRL_GCM_SET_TAG == 0 || EVP_CTRL_GCM_GET_TAG == 0 || EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAVE_EVPGCM 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } unsupported_algorithms="$unsupported_cipers \ aes128-gcm@openssh.com aes256-gcm@openssh.com" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking for library containing EVP_CIPHER_CTX_ctrl" >&5 echo $ECHO_N "checking for library containing EVP_CIPHER_CTX_ctrl... $ECHO_C" >&6; } if test "${ac_cv_search_EVP_CIPHER_CTX_ctrl+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char EVP_CIPHER_CTX_ctrl (); int main () { return EVP_CIPHER_CTX_ctrl (); ; return 0; } _ACEOF for ac_lib in '' crypto; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_EVP_CIPHER_CTX_ctrl=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_EVP_CIPHER_CTX_ctrl+set}" = set; then break fi done if test "${ac_cv_search_EVP_CIPHER_CTX_ctrl+set}" = set; then : else ac_cv_search_EVP_CIPHER_CTX_ctrl=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_EVP_CIPHER_CTX_ctrl" >&5 echo "${ECHO_T}$ac_cv_search_EVP_CIPHER_CTX_ctrl" >&6; } ac_res=$ac_cv_search_EVP_CIPHER_CTX_ctrl if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_EVP_CIPHER_CTX_CTRL 1 _ACEOF fi { echo "$as_me:$LINENO: checking if EVP_DigestUpdate returns an int" >&5 echo $ECHO_N "checking if EVP_DigestUpdate returns an int... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { if(EVP_DigestUpdate(NULL, NULL,0)) exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define OPENSSL_EVP_DIGESTUPDATE_VOID 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, # because the system crypt() is more featureful. if test "x$check_for_libcrypt_before" = "x1"; then { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6; } if test $ac_cv_lib_crypt_crypt = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPT 1 _ACEOF LIBS="-lcrypt $LIBS" fi fi # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the # version in OpenSSL. if test "x$check_for_libcrypt_later" = "x1"; then { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6; } if test $ac_cv_lib_crypt_crypt = yes; then LIBS="$LIBS -lcrypt" fi fi for ac_func in crypt DES_crypt do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # Search for SHA256 support in libc and/or OpenSSL for ac_func in SHA256_Update EVP_sha256 do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else unsupported_algorithms="$unsupported_algorithms \ hmac-sha2-256 hmac-sha2-512 \ diffie-hellman-group-exchange-sha256 \ hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" fi done # Search for RIPE-MD support in OpenSSL for ac_func in EVP_ripemd160 do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else unsupported_algorithms="$unsupported_algorithms \ hmac-ripemd160 hmac-ripemd160@openssh.com hmac-ripemd160-etm@openssh.com" fi done # Check complete ECC support in OpenSSL { echo "$as_me:$LINENO: checking whether OpenSSL has NID_X9_62_prime256v1" >&5 echo $ECHO_N "checking whether OpenSSL has NID_X9_62_prime256v1... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif int main () { EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); const EVP_MD *m = EVP_sha256(); /* We need this too */ ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } enable_nistp256=1 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking whether OpenSSL has NID_secp384r1" >&5 echo $ECHO_N "checking whether OpenSSL has NID_secp384r1... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif int main () { EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); const EVP_MD *m = EVP_sha384(); /* We need this too */ ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } enable_nistp384=1 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking whether OpenSSL has NID_secp521r1" >&5 echo $ECHO_N "checking whether OpenSSL has NID_secp521r1... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ # error "OpenSSL < 0.9.8g has unreliable ECC code" #endif int main () { EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } { echo "$as_me:$LINENO: checking if OpenSSL's NID_secp521r1 is functional" >&5 echo $ECHO_N "checking if OpenSSL's NID_secp521r1 is functional... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross-compiling: assuming yes" >&5 echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;} enable_nistp521=1 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #include int main () { EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ exit(e == NULL || m == NULL); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } enable_nistp521=1 else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext COMMENT_OUT_ECC="#no ecc#" TEST_SSH_ECC=no if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ test x$enable_nistp521 = x1; then cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAS_ECC 1 _ACEOF fi if test x$enable_nistp256 = x1; then cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAS_NISTP256 1 _ACEOF TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" fi if test x$enable_nistp384 = x1; then cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAS_NISTP384 1 _ACEOF TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" fi if test x$enable_nistp521 = x1; then cat >>confdefs.h <<\_ACEOF #define OPENSSL_HAS_NISTP521 1 _ACEOF TEST_SSH_ECC=yes COMMENT_OUT_ECC="" else unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" fi else { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6; } if test $ac_cv_lib_crypt_crypt = yes; then LIBS="$LIBS -lcrypt" fi for ac_func in crypt do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi for ac_func in \ arc4random \ arc4random_buf \ arc4random_stir \ arc4random_uniform \ do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done saved_LIBS="$LIBS" { echo "$as_me:$LINENO: checking for ia_openinfo in -liaf" >&5 echo $ECHO_N "checking for ia_openinfo in -liaf... $ECHO_C" >&6; } if test "${ac_cv_lib_iaf_ia_openinfo+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-liaf $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ia_openinfo (); int main () { return ia_openinfo (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_iaf_ia_openinfo=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_iaf_ia_openinfo=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_iaf_ia_openinfo" >&5 echo "${ECHO_T}$ac_cv_lib_iaf_ia_openinfo" >&6; } if test $ac_cv_lib_iaf_ia_openinfo = yes; then LIBS="$LIBS -liaf" for ac_func in set_id do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF SSHDLIBS="$SSHDLIBS -liaf" cat >>confdefs.h <<\_ACEOF #define HAVE_LIBIAF 1 _ACEOF fi done fi LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself if test "x$openssl" = "xyes" ; then { echo "$as_me:$LINENO: checking whether OpenSSL's PRNG is internally seeded" >&5 echo $ECHO_N "checking whether OpenSSL's PRNG is internally seeded... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming yes" >&5 echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} # This is safe, since we will fatal() at runtime if # OpenSSL is not seeded correctly. OPENSSL_SEEDS_ITSELF=yes else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { exit(RAND_status() == 1 ? 0 : 1); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then OPENSSL_SEEDS_ITSELF=yes { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi # PRNGD TCP socket # Check whether --with-prngd-port was given. if test "${with_prngd_port+set}" = set; then withval=$with_prngd_port; case "$withval" in no) withval="" ;; [0-9]*) ;; *) { { echo "$as_me:$LINENO: error: You must specify a numeric port number for --with-prngd-port" >&5 echo "$as_me: error: You must specify a numeric port number for --with-prngd-port" >&2;} { (exit 1); exit 1; }; } ;; esac if test ! -z "$withval" ; then PRNGD_PORT="$withval" cat >>confdefs.h <<_ACEOF #define PRNGD_PORT $PRNGD_PORT _ACEOF fi fi # PRNGD Unix domain socket # Check whether --with-prngd-socket was given. if test "${with_prngd_socket+set}" = set; then withval=$with_prngd_socket; case "$withval" in yes) withval="/var/run/egd-pool" ;; no) withval="" ;; /*) ;; *) { { echo "$as_me:$LINENO: error: You must specify an absolute path to the entropy socket" >&5 echo "$as_me: error: You must specify an absolute path to the entropy socket" >&2;} { (exit 1); exit 1; }; } ;; esac if test ! -z "$withval" ; then if test ! -z "$PRNGD_PORT" ; then { { echo "$as_me:$LINENO: error: You may not specify both a PRNGD/EGD port and socket" >&5 echo "$as_me: error: You may not specify both a PRNGD/EGD port and socket" >&2;} { (exit 1); exit 1; }; } fi if test ! -r "$withval" ; then { echo "$as_me:$LINENO: WARNING: Entropy socket is not readable" >&5 echo "$as_me: WARNING: Entropy socket is not readable" >&2;} fi PRNGD_SOCKET="$withval" cat >>confdefs.h <<_ACEOF #define PRNGD_SOCKET "$PRNGD_SOCKET" _ACEOF fi else # Check for existing socket only if we don't have a random device already if test "x$OPENSSL_SEEDS_ITSELF" != "xyes" ; then { echo "$as_me:$LINENO: checking for PRNGD/EGD socket" >&5 echo $ECHO_N "checking for PRNGD/EGD socket... $ECHO_C" >&6; } # Insert other locations here for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then PRNGD_SOCKET="$sock" cat >>confdefs.h <<_ACEOF #define PRNGD_SOCKET "$PRNGD_SOCKET" _ACEOF break; fi done if test ! -z "$PRNGD_SOCKET" ; then { echo "$as_me:$LINENO: result: $PRNGD_SOCKET" >&5 echo "${ECHO_T}$PRNGD_SOCKET" >&6; } else { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } fi fi fi # Which randomness source do we use? if test ! -z "$PRNGD_PORT" ; then RAND_MSG="PRNGd port $PRNGD_PORT" elif test ! -z "$PRNGD_SOCKET" ; then RAND_MSG="PRNGd socket $PRNGD_SOCKET" elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then cat >>confdefs.h <<\_ACEOF #define OPENSSL_PRNG_ONLY 1 _ACEOF RAND_MSG="OpenSSL internal ONLY" elif test "x$openssl" = "xno" ; then { echo "$as_me:$LINENO: WARNING: OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible" >&5 echo "$as_me: WARNING: OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible" >&2;} else { { echo "$as_me:$LINENO: error: OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options" >&5 echo "$as_me: error: OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options" >&2;} { (exit 1); exit 1; }; } fi # Check for PAM libs PAM_MSG="no" # Check whether --with-pam was given. if test "${with_pam+set}" = set; then withval=$with_pam; if test "x$withval" != "xno" ; then if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \ test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then { { echo "$as_me:$LINENO: error: PAM headers not found" >&5 echo "$as_me: error: PAM headers not found" >&2;} { (exit 1); exit 1; }; } fi saved_LIBS="$LIBS" { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { echo "$as_me:$LINENO: checking for pam_set_item in -lpam" >&5 echo $ECHO_N "checking for pam_set_item in -lpam... $ECHO_C" >&6; } if test "${ac_cv_lib_pam_pam_set_item+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_set_item (); int main () { return pam_set_item (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_pam_pam_set_item=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pam_pam_set_item=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_set_item" >&5 echo "${ECHO_T}$ac_cv_lib_pam_pam_set_item" >&6; } if test $ac_cv_lib_pam_pam_set_item = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else { { echo "$as_me:$LINENO: error: *** libpam missing" >&5 echo "$as_me: error: *** libpam missing" >&2;} { (exit 1); exit 1; }; } fi for ac_func in pam_getenvlist do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in pam_putenv do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS="$saved_LIBS" PAM_MSG="yes" SSHDLIBS="$SSHDLIBS -lpam" cat >>confdefs.h <<\_ACEOF #define USE_PAM 1 _ACEOF if test $ac_cv_lib_dl_dlopen = yes; then case "$LIBS" in *-ldl*) # libdl already in LIBS ;; *) SSHDLIBS="$SSHDLIBS -ldl" ;; esac fi fi fi # Check for older PAM if test "x$PAM_MSG" = "xyes" ; then # Check PAM strerror arguments (old PAM) { echo "$as_me:$LINENO: checking whether pam_strerror takes only one argument" >&5 echo $ECHO_N "checking whether pam_strerror takes only one argument... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if defined(HAVE_SECURITY_PAM_APPL_H) #include #elif defined (HAVE_PAM_PAM_APPL_H) #include #endif int main () { (void)pam_strerror((pam_handle_t *)NULL, -1); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >>confdefs.h <<\_ACEOF #define HAVE_OLD_PAM 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } PAM_MSG="yes (old library)" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi case "$host" in *-*-cygwin*) SSH_PRIVSEP_USER=CYGWIN_SSH_PRIVSEP_USER ;; *) SSH_PRIVSEP_USER=sshd ;; esac # Check whether --with-privsep-user was given. if test "${with_privsep_user+set}" = set; then withval=$with_privsep_user; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then SSH_PRIVSEP_USER=$withval fi fi if test "x$SSH_PRIVSEP_USER" = "xCYGWIN_SSH_PRIVSEP_USER" ; then cat >>confdefs.h <<_ACEOF #define SSH_PRIVSEP_USER CYGWIN_SSH_PRIVSEP_USER _ACEOF else cat >>confdefs.h <<_ACEOF #define SSH_PRIVSEP_USER "$SSH_PRIVSEP_USER" _ACEOF fi if test "x$have_linux_no_new_privs" = "x1" ; then { echo "$as_me:$LINENO: checking whether SECCOMP_MODE_FILTER is declared" >&5 echo $ECHO_N "checking whether SECCOMP_MODE_FILTER is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_SECCOMP_MODE_FILTER+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef SECCOMP_MODE_FILTER (void) SECCOMP_MODE_FILTER; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_SECCOMP_MODE_FILTER=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_SECCOMP_MODE_FILTER=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_SECCOMP_MODE_FILTER" >&5 echo "${ECHO_T}$ac_cv_have_decl_SECCOMP_MODE_FILTER" >&6; } if test $ac_cv_have_decl_SECCOMP_MODE_FILTER = yes; then have_seccomp_filter=1 fi fi if test "x$have_seccomp_filter" = "x1" ; then { echo "$as_me:$LINENO: checking kernel for seccomp_filter support" >&5 echo $ECHO_N "checking kernel for seccomp_filter support... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include #include int main () { int i = $seccomp_audit_arch; errno = 0; prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); exit(errno == EFAULT ? 0 : 1); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } # Disable seccomp filter as a target have_seccomp_filter=0 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi # Decide which sandbox style to use sandbox_arg="" # Check whether --with-sandbox was given. if test "${with_sandbox+set}" = set; then withval=$with_sandbox; if test "x$withval" = "xyes" ; then sandbox_arg="" else sandbox_arg="$withval" fi fi # Some platforms (seems to be the ones that have a kernel poll(2)-type # function with which they implement select(2)) use an extra file descriptor # when calling select(2), which means we can't use the rlimit sandbox. { echo "$as_me:$LINENO: checking if select works with descriptor rlimit" >&5 echo $ECHO_N "checking if select works with descriptor rlimit... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming yes" >&5 echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_TIME_H # include #endif #include #ifdef HAVE_SYS_SELECT_H # include #endif #include #include #include int main () { struct rlimit rl_zero; int fd, r; fd_set fds; struct timeval tv; fd = open("/dev/null", O_RDONLY); FD_ZERO(&fds); FD_SET(fd, &fds); rl_zero.rlim_cur = rl_zero.rlim_max = 0; setrlimit(RLIMIT_FSIZE, &rl_zero); setrlimit(RLIMIT_NOFILE, &rl_zero); tv.tv_sec = 1; tv.tv_usec = 0; r = select(fd+1, &fds, NULL, NULL, &tv); exit (r == -1 ? 1 : 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } select_works_with_rlimit=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } select_works_with_rlimit=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking if setrlimit(RLIMIT_NOFILE,{0,0}) works" >&5 echo $ECHO_N "checking if setrlimit(RLIMIT_NOFILE,{0,0}) works... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming yes" >&5 echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include int main () { struct rlimit rl_zero; int fd, r; fd_set fds; rl_zero.rlim_cur = rl_zero.rlim_max = 0; r = setrlimit(RLIMIT_NOFILE, &rl_zero); exit (r == -1 ? 1 : 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rlimit_nofile_zero_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } rlimit_nofile_zero_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking if setrlimit RLIMIT_FSIZE works" >&5 echo $ECHO_N "checking if setrlimit RLIMIT_FSIZE works... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: assuming yes" >&5 echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { struct rlimit rl_zero; rl_zero.rlim_cur = rl_zero.rlim_max = 0; exit(setrlimit(RLIMIT_FSIZE, &rl_zero) != 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF #define SANDBOX_SKIP_RLIMIT_FSIZE 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi if test "x$sandbox_arg" = "xpledge" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then test "x$ac_cv_func_pledge" != "xyes" && \ { { echo "$as_me:$LINENO: error: pledge sandbox requires pledge(2) support" >&5 echo "$as_me: error: pledge sandbox requires pledge(2) support" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="pledge" cat >>confdefs.h <<\_ACEOF #define SANDBOX_PLEDGE 1 _ACEOF elif test "x$sandbox_arg" = "xsystrace" || \ ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then test "x$have_systr_policy_kill" != "x1" && \ { { echo "$as_me:$LINENO: error: systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" >&5 echo "$as_me: error: systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="systrace" cat >>confdefs.h <<\_ACEOF #define SANDBOX_SYSTRACE 1 _ACEOF elif test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ "x$ac_cv_header_sandbox_h" != "xyes" && \ { { echo "$as_me:$LINENO: error: Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" >&5 echo "$as_me: error: Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="darwin" cat >>confdefs.h <<\_ACEOF #define SANDBOX_DARWIN 1 _ACEOF elif test "x$sandbox_arg" = "xseccomp_filter" || \ ( test -z "$sandbox_arg" && \ test "x$have_seccomp_filter" = "x1" && \ test "x$ac_cv_header_elf_h" = "xyes" && \ test "x$ac_cv_header_linux_audit_h" = "xyes" && \ test "x$ac_cv_header_linux_filter_h" = "xyes" && \ test "x$seccomp_audit_arch" != "x" && \ test "x$have_linux_no_new_privs" = "x1" && \ test "x$ac_cv_func_prctl" = "xyes" ) ; then test "x$seccomp_audit_arch" = "x" && \ { { echo "$as_me:$LINENO: error: seccomp_filter sandbox not supported on $host" >&5 echo "$as_me: error: seccomp_filter sandbox not supported on $host" >&2;} { (exit 1); exit 1; }; } test "x$have_linux_no_new_privs" != "x1" && \ { { echo "$as_me:$LINENO: error: seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS" >&5 echo "$as_me: error: seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS" >&2;} { (exit 1); exit 1; }; } test "x$have_seccomp_filter" != "x1" && \ { { echo "$as_me:$LINENO: error: seccomp_filter sandbox requires seccomp headers" >&5 echo "$as_me: error: seccomp_filter sandbox requires seccomp headers" >&2;} { (exit 1); exit 1; }; } test "x$ac_cv_func_prctl" != "xyes" && \ { { echo "$as_me:$LINENO: error: seccomp_filter sandbox requires prctl function" >&5 echo "$as_me: error: seccomp_filter sandbox requires prctl function" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="seccomp_filter" cat >>confdefs.h <<\_ACEOF #define SANDBOX_SECCOMP_FILTER 1 _ACEOF elif test "x$sandbox_arg" = "xcapsicum" || \ ( test -z "$sandbox_arg" && \ test "x$ac_cv_header_sys_capability_h" = "xyes" && \ test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then test "x$ac_cv_header_sys_capability_h" != "xyes" && \ { { echo "$as_me:$LINENO: error: capsicum sandbox requires sys/capability.h header" >&5 echo "$as_me: error: capsicum sandbox requires sys/capability.h header" >&2;} { (exit 1); exit 1; }; } test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ { { echo "$as_me:$LINENO: error: capsicum sandbox requires cap_rights_limit function" >&5 echo "$as_me: error: capsicum sandbox requires cap_rights_limit function" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="capsicum" cat >>confdefs.h <<\_ACEOF #define SANDBOX_CAPSICUM 1 _ACEOF elif test "x$sandbox_arg" = "xrlimit" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \ test "x$select_works_with_rlimit" = "xyes" && \ test "x$rlimit_nofile_zero_works" = "xyes" ) ; then test "x$ac_cv_func_setrlimit" != "xyes" && \ { { echo "$as_me:$LINENO: error: rlimit sandbox requires setrlimit function" >&5 echo "$as_me: error: rlimit sandbox requires setrlimit function" >&2;} { (exit 1); exit 1; }; } test "x$select_works_with_rlimit" != "xyes" && \ { { echo "$as_me:$LINENO: error: rlimit sandbox requires select to work with rlimit" >&5 echo "$as_me: error: rlimit sandbox requires select to work with rlimit" >&2;} { (exit 1); exit 1; }; } SANDBOX_STYLE="rlimit" cat >>confdefs.h <<\_ACEOF #define SANDBOX_RLIMIT 1 _ACEOF elif test "x$sandbox_arg" = "xsolaris" || \ ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then SANDBOX_STYLE="solaris" cat >>confdefs.h <<\_ACEOF #define SANDBOX_SOLARIS 1 _ACEOF elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then SANDBOX_STYLE="none" cat >>confdefs.h <<\_ACEOF #define SANDBOX_NULL 1 _ACEOF else { { echo "$as_me:$LINENO: error: unsupported --with-sandbox" >&5 echo "$as_me: error: unsupported --with-sandbox" >&2;} { (exit 1); exit 1; }; } fi # Cheap hack to ensure NEWS-OS libraries are arranged right. if test ! -z "$SONY" ; then LIBS="$LIBS -liberty"; fi # Check for long long datatypes { echo "$as_me:$LINENO: checking for long long" >&5 echo $ECHO_N "checking for long long... $ECHO_C" >&6; } if test "${ac_cv_type_long_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5 echo "${ECHO_T}$ac_cv_type_long_long" >&6; } if test $ac_cv_type_long_long = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LONG_LONG 1 _ACEOF fi { echo "$as_me:$LINENO: checking for unsigned long long" >&5 echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6; } if test "${ac_cv_type_unsigned_long_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef unsigned long long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_unsigned_long_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_unsigned_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5 echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6; } if test $ac_cv_type_unsigned_long_long = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UNSIGNED_LONG_LONG 1 _ACEOF fi { echo "$as_me:$LINENO: checking for long double" >&5 echo $ECHO_N "checking for long double... $ECHO_C" >&6; } if test "${ac_cv_type_long_double+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long double ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_double=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_double=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_double" >&5 echo "${ECHO_T}$ac_cv_type_long_double" >&6; } if test $ac_cv_type_long_double = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LONG_DOUBLE 1 _ACEOF fi # Check datatype sizes { echo "$as_me:$LINENO: checking for short int" >&5 echo $ECHO_N "checking for short int... $ECHO_C" >&6; } if test "${ac_cv_type_short_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_short_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_short_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_short_int" >&5 echo "${ECHO_T}$ac_cv_type_short_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of short int" >&5 echo $ECHO_N "checking size of short int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_short_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_short_int=$ac_lo;; '') if test "$ac_cv_type_short_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (short int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (short int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_short_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef short int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_short_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_short_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (short int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (short int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_short_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_short_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_short_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT_INT $ac_cv_sizeof_short_int _ACEOF { echo "$as_me:$LINENO: checking for int" >&5 echo $ECHO_N "checking for int... $ECHO_C" >&6; } if test "${ac_cv_type_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 echo "${ECHO_T}$ac_cv_type_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_int=$ac_lo;; '') if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF { echo "$as_me:$LINENO: checking for long int" >&5 echo $ECHO_N "checking for long int... $ECHO_C" >&6; } if test "${ac_cv_type_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_int" >&5 echo "${ECHO_T}$ac_cv_type_long_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of long int" >&5 echo $ECHO_N "checking size of long int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long_int=$ac_lo;; '') if test "$ac_cv_type_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF { echo "$as_me:$LINENO: checking for long long int" >&5 echo $ECHO_N "checking for long long int... $ECHO_C" >&6; } if test "${ac_cv_type_long_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_long_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_long_int" >&5 echo "${ECHO_T}$ac_cv_type_long_long_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of long long int" >&5 echo $ECHO_N "checking size of long long int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long_long_int=$ac_lo;; '') if test "$ac_cv_type_long_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_long_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long_long_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_long_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_long_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int _ACEOF # Sanity check long long for some platforms (AIX) if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then ac_cv_sizeof_long_long_int=0 fi # compute LLONG_MIN and LLONG_MAX if we don't know them. if test -z "$have_llong_max"; then { echo "$as_me:$LINENO: checking for max value of long long" >&5 echo $ECHO_N "checking for max value of long long... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking" >&5 echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Why is this so damn hard? */ #ifdef __GNUC__ # undef __GNUC__ #endif #define __USE_ISOC99 #include #define DATA "conftest.llminmax" #define my_abs(a) ((a) < 0 ? ((a) * -1) : (a)) /* * printf in libc on some platforms (eg old Tru64) does not understand %lld so * we do this the hard way. */ static int fprint_ll(FILE *f, long long n) { unsigned int i; int l[sizeof(long long) * 8]; if (n < 0) if (fprintf(f, "-") < 0) return -1; for (i = 0; n != 0; i++) { l[i] = my_abs(n % 10); n /= 10; } do { if (fprintf(f, "%d", l[--i]) < 0) return -1; } while (i != 0); if (fprintf(f, " ") < 0) return -1; return 0; } int main () { FILE *f; long long i, llmin, llmax = 0; if((f = fopen(DATA,"w")) == NULL) exit(1); #if defined(LLONG_MIN) && defined(LLONG_MAX) fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n"); llmin = LLONG_MIN; llmax = LLONG_MAX; #else fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n"); /* This will work on one's complement and two's complement */ for (i = 1; i > llmax; i <<= 1, i++) llmax = i; llmin = llmax + 1LL; /* wrap */ #endif /* Sanity check */ if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax || llmax - 1 > llmax || llmin == llmax || llmin == 0 || llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) { fprintf(f, "unknown unknown\n"); exit(2); } if (fprint_ll(f, llmin) < 0) exit(3); if (fprint_ll(f, llmax) < 0) exit(4); if (fclose(f) < 0) exit(5); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then llong_min=`$AWK '{print $1}' conftest.llminmax` llong_max=`$AWK '{print $2}' conftest.llminmax` { echo "$as_me:$LINENO: result: $llong_max" >&5 echo "${ECHO_T}$llong_max" >&6; } cat >>confdefs.h <<_ACEOF #define LLONG_MAX ${llong_max}LL _ACEOF { echo "$as_me:$LINENO: checking for min value of long long" >&5 echo $ECHO_N "checking for min value of long long... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $llong_min" >&5 echo "${ECHO_T}$llong_min" >&6; } cat >>confdefs.h <<_ACEOF #define LLONG_MIN ${llong_min}LL _ACEOF else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { echo "$as_me:$LINENO: result: not found" >&5 echo "${ECHO_T}not found" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi # More checks for data types { echo "$as_me:$LINENO: checking for u_int type" >&5 echo $ECHO_N "checking for u_int type... $ECHO_C" >&6; } if test "${ac_cv_have_u_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_int a; a = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_u_int="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_u_int="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_u_int" >&5 echo "${ECHO_T}$ac_cv_have_u_int" >&6; } if test "x$ac_cv_have_u_int" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INT 1 _ACEOF have_u_int=1 fi { echo "$as_me:$LINENO: checking for intXX_t types" >&5 echo $ECHO_N "checking for intXX_t types... $ECHO_C" >&6; } if test "${ac_cv_have_intxx_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_intxx_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_intxx_t" >&5 echo "${ECHO_T}$ac_cv_have_intxx_t" >&6; } if test "x$ac_cv_have_intxx_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_INTXX_T 1 _ACEOF have_intxx_t=1 fi if (test -z "$have_intxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then { echo "$as_me:$LINENO: checking for intXX_t types in stdint.h" >&5 echo $ECHO_N "checking for intXX_t types in stdint.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_INTXX_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking for int64_t type" >&5 echo $ECHO_N "checking for int64_t type... $ECHO_C" >&6; } if test "${ac_cv_have_int64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_STDINT_H # include #endif #include #ifdef HAVE_SYS_BITYPES_H # include #endif int main () { int64_t a; a = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_int64_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_int64_t" >&5 echo "${ECHO_T}$ac_cv_have_int64_t" >&6; } if test "x$ac_cv_have_int64_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_INT64_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for u_intXX_t types" >&5 echo $ECHO_N "checking for u_intXX_t types... $ECHO_C" >&6; } if test "${ac_cv_have_u_intxx_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_u_intxx_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_u_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_u_intxx_t" >&5 echo "${ECHO_T}$ac_cv_have_u_intxx_t" >&6; } if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INTXX_T 1 _ACEOF have_u_intxx_t=1 fi if test -z "$have_u_intxx_t" ; then { echo "$as_me:$LINENO: checking for u_intXX_t types in sys/socket.h" >&5 echo $ECHO_N "checking for u_intXX_t types in sys/socket.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INTXX_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking for u_int64_t types" >&5 echo $ECHO_N "checking for u_int64_t types... $ECHO_C" >&6; } if test "${ac_cv_have_u_int64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_int64_t a; a = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_u_int64_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_u_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_u_int64_t" >&5 echo "${ECHO_T}$ac_cv_have_u_int64_t" >&6; } if test "x$ac_cv_have_u_int64_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INT64_T 1 _ACEOF have_u_int64_t=1 fi if (test -z "$have_u_int64_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { echo "$as_me:$LINENO: checking for u_int64_t type in sys/bitypes.h" >&5 echo $ECHO_N "checking for u_int64_t type in sys/bitypes.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_int64_t a; a = 1 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INT64_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$have_u_intxx_t" ; then { echo "$as_me:$LINENO: checking for uintXX_t types" >&5 echo $ECHO_N "checking for uintXX_t types... $ECHO_C" >&6; } if test "${ac_cv_have_uintxx_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_uintxx_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_uintxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_uintxx_t" >&5 echo "${ECHO_T}$ac_cv_have_uintxx_t" >&6; } if test "x$ac_cv_have_uintxx_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_UINTXX_T 1 _ACEOF fi fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then { echo "$as_me:$LINENO: checking for uintXX_t types in stdint.h" >&5 echo $ECHO_N "checking for uintXX_t types in stdint.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_UINTXX_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_inttypes_h" = "xyes") then { echo "$as_me:$LINENO: checking for uintXX_t types in inttypes.h" >&5 echo $ECHO_N "checking for uintXX_t types in inttypes.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_UINTXX_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { echo "$as_me:$LINENO: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 echo $ECHO_N "checking for intXX_t and u_intXX_t types in sys/bitypes.h... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; u_int8_t e; u_int16_t f; u_int32_t g; a = b = c = e = f = g = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_INTXX_T 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_INTXX_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: checking for u_char" >&5 echo $ECHO_N "checking for u_char... $ECHO_C" >&6; } if test "${ac_cv_have_u_char+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { u_char foo; foo = 125; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_u_char="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_u_char="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_u_char" >&5 echo "${ECHO_T}$ac_cv_have_u_char" >&6; } if test "x$ac_cv_have_u_char" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_U_CHAR 1 _ACEOF fi { echo "$as_me:$LINENO: checking for intmax_t" >&5 echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6; } if test "${ac_cv_type_intmax_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef intmax_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_intmax_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_intmax_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5 echo "${ECHO_T}$ac_cv_type_intmax_t" >&6; } if test $ac_cv_type_intmax_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INTMAX_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for uintmax_t" >&5 echo $ECHO_N "checking for uintmax_t... $ECHO_C" >&6; } if test "${ac_cv_type_uintmax_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef uintmax_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_uintmax_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_uintmax_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_uintmax_t" >&5 echo "${ECHO_T}$ac_cv_type_uintmax_t" >&6; } if test $ac_cv_type_uintmax_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_UINTMAX_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; } if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef socklen_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6; } if test $ac_cv_type_socklen_t = yes; then : else { echo "$as_me:$LINENO: checking for socklen_t equivalent" >&5 echo $ECHO_N "checking for socklen_t equivalent... $ECHO_C" >&6; } if test "${curl_cv_socklen_t_equiv+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # 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 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int getpeername (int, $arg2 *, $t *); int main () { $t len; getpeername(0,0,&len); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then curl_cv_socklen_t_equiv="$t" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done if test "x$curl_cv_socklen_t_equiv" = x; then { { echo "$as_me:$LINENO: error: Cannot find a type to use in place of socklen_t" >&5 echo "$as_me: error: Cannot find a type to use in place of socklen_t" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $curl_cv_socklen_t_equiv" >&5 echo "${ECHO_T}$curl_cv_socklen_t_equiv" >&6; } cat >>confdefs.h <<_ACEOF #define socklen_t $curl_cv_socklen_t_equiv _ACEOF fi { echo "$as_me:$LINENO: checking for sig_atomic_t" >&5 echo $ECHO_N "checking for sig_atomic_t... $ECHO_C" >&6; } if test "${ac_cv_type_sig_atomic_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include typedef sig_atomic_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_sig_atomic_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_sig_atomic_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_sig_atomic_t" >&5 echo "${ECHO_T}$ac_cv_type_sig_atomic_t" >&6; } if test $ac_cv_type_sig_atomic_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SIG_ATOMIC_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for fsblkcnt_t" >&5 echo $ECHO_N "checking for fsblkcnt_t... $ECHO_C" >&6; } if test "${ac_cv_type_fsblkcnt_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_BITYPES_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif typedef fsblkcnt_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_fsblkcnt_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_fsblkcnt_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_fsblkcnt_t" >&5 echo "${ECHO_T}$ac_cv_type_fsblkcnt_t" >&6; } if test $ac_cv_type_fsblkcnt_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_FSBLKCNT_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for fsfilcnt_t" >&5 echo $ECHO_N "checking for fsfilcnt_t... $ECHO_C" >&6; } if test "${ac_cv_type_fsfilcnt_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_BITYPES_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif typedef fsfilcnt_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_fsfilcnt_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_fsfilcnt_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_fsfilcnt_t" >&5 echo "${ECHO_T}$ac_cv_type_fsfilcnt_t" >&6; } if test $ac_cv_type_fsfilcnt_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_FSFILCNT_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for in_addr_t" >&5 echo $ECHO_N "checking for in_addr_t... $ECHO_C" >&6; } if test "${ac_cv_type_in_addr_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef in_addr_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_in_addr_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_in_addr_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_in_addr_t" >&5 echo "${ECHO_T}$ac_cv_type_in_addr_t" >&6; } if test $ac_cv_type_in_addr_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_IN_ADDR_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for in_port_t" >&5 echo $ECHO_N "checking for in_port_t... $ECHO_C" >&6; } if test "${ac_cv_type_in_port_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef in_port_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_in_port_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_in_port_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_in_port_t" >&5 echo "${ECHO_T}$ac_cv_type_in_port_t" >&6; } if test $ac_cv_type_in_port_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_IN_PORT_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_have_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { size_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_size_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_size_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_size_t" >&5 echo "${ECHO_T}$ac_cv_have_size_t" >&6; } if test "x$ac_cv_have_size_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SIZE_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for ssize_t" >&5 echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6; } if test "${ac_cv_have_ssize_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { ssize_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_ssize_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_ssize_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_ssize_t" >&5 echo "${ECHO_T}$ac_cv_have_ssize_t" >&6; } if test "x$ac_cv_have_ssize_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SSIZE_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for clock_t" >&5 echo $ECHO_N "checking for clock_t... $ECHO_C" >&6; } if test "${ac_cv_have_clock_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { clock_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_clock_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_clock_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_clock_t" >&5 echo "${ECHO_T}$ac_cv_have_clock_t" >&6; } if test "x$ac_cv_have_clock_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_CLOCK_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for sa_family_t" >&5 echo $ECHO_N "checking for sa_family_t... $ECHO_C" >&6; } if test "${ac_cv_have_sa_family_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { sa_family_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_sa_family_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { sa_family_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_sa_family_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_sa_family_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_sa_family_t" >&5 echo "${ECHO_T}$ac_cv_have_sa_family_t" >&6; } if test "x$ac_cv_have_sa_family_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SA_FAMILY_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_have_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { pid_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_pid_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_pid_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_pid_t" >&5 echo "${ECHO_T}$ac_cv_have_pid_t" >&6; } if test "x$ac_cv_have_pid_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_PID_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for mode_t" >&5 echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; } if test "${ac_cv_have_mode_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { mode_t foo; foo = 1235; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_mode_t="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_mode_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_mode_t" >&5 echo "${ECHO_T}$ac_cv_have_mode_t" >&6; } if test "x$ac_cv_have_mode_t" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_MODE_T 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6; } if test "${ac_cv_have_struct_sockaddr_storage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_struct_sockaddr_storage="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_struct_sockaddr_storage="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_struct_sockaddr_storage" >&5 echo "${ECHO_T}$ac_cv_have_struct_sockaddr_storage" >&6; } if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5 echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6; } if test "${ac_cv_have_struct_sockaddr_in6+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 s; s.sin6_family = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_struct_sockaddr_in6="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_struct_sockaddr_in6="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_struct_sockaddr_in6" >&5 echo "${ECHO_T}$ac_cv_have_struct_sockaddr_in6" >&6; } if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_SOCKADDR_IN6 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct in6_addr" >&5 echo $ECHO_N "checking for struct in6_addr... $ECHO_C" >&6; } if test "${ac_cv_have_struct_in6_addr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct in6_addr s; s.s6_addr[0] = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_struct_in6_addr="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_struct_in6_addr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_struct_in6_addr" >&5 echo "${ECHO_T}$ac_cv_have_struct_in6_addr" >&6; } if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_IN6_ADDR 1 _ACEOF { echo "$as_me:$LINENO: checking for struct sockaddr_in6.sin6_scope_id" >&5 echo $ECHO_N "checking for struct sockaddr_in6.sin6_scope_id... $ECHO_C" >&6; } if test "${ac_cv_member_struct_sockaddr_in6_sin6_scope_id+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #include int main () { static struct sockaddr_in6 ac_aggr; if (ac_aggr.sin6_scope_id) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_sockaddr_in6_sin6_scope_id=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #include int main () { static struct sockaddr_in6 ac_aggr; if (sizeof ac_aggr.sin6_scope_id) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_sockaddr_in6_sin6_scope_id=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_sockaddr_in6_sin6_scope_id=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_in6_sin6_scope_id" >&5 echo "${ECHO_T}$ac_cv_member_struct_sockaddr_in6_sin6_scope_id" >&6; } if test $ac_cv_member_struct_sockaddr_in6_sin6_scope_id = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 _ACEOF fi fi { echo "$as_me:$LINENO: checking for struct addrinfo" >&5 echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6; } if test "${ac_cv_have_struct_addrinfo+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { struct addrinfo s; s.ai_flags = AI_PASSIVE; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_struct_addrinfo="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_struct_addrinfo="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_struct_addrinfo" >&5 echo "${ECHO_T}$ac_cv_have_struct_addrinfo" >&6; } if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_ADDRINFO 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct timeval" >&5 echo $ECHO_N "checking for struct timeval... $ECHO_C" >&6; } if test "${ac_cv_have_struct_timeval+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct timeval tv; tv.tv_sec = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_struct_timeval="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_struct_timeval="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_struct_timeval" >&5 echo "${ECHO_T}$ac_cv_have_struct_timeval" >&6; } if test "x$ac_cv_have_struct_timeval" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_TIMEVAL 1 _ACEOF have_struct_timeval=1 fi { echo "$as_me:$LINENO: checking for struct timespec" >&5 echo $ECHO_N "checking for struct timespec... $ECHO_C" >&6; } if test "${ac_cv_type_struct_timespec+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef struct timespec ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_struct_timespec=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_struct_timespec=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_struct_timespec" >&5 echo "${ECHO_T}$ac_cv_type_struct_timespec" >&6; } if test $ac_cv_type_struct_timespec = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_TIMESPEC 1 _ACEOF fi # We need int64_t or else certian parts of the compile will fail. if test "x$ac_cv_have_int64_t" = "xno" && \ test "x$ac_cv_sizeof_long_int" != "x8" && \ test "x$ac_cv_sizeof_long_long_int" = "x0" ; then echo "OpenSSH requires int64_t support. Contact your vendor or install" echo "an alternative compiler (I.E., GCC) before continuing." echo "" exit 1; else if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: Assuming working snprintf()" >&5 echo "$as_me: WARNING: cross compiling: Assuming working snprintf()" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_SNPRINTF main() { char buf[50]; char expected_out[50]; int mazsize = 50 ; #if (SIZEOF_LONG_INT == 8) long int num = 0x7fffffffffffffff; #else long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); snprintf(buf, mazsize, "%lld", num); if(strcmp(buf, expected_out) != 0) exit(1); exit(0); } #else main() { exit(0); } #endif _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then true else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) cat >>confdefs.h <<\_ACEOF #define BROKEN_SNPRINTF 1 _ACEOF fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi # look for field 'ut_host' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host { echo "$as_me:$LINENO: checking for ut_host field in utmp.h" >&5 echo $ECHO_N "checking for ut_host field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_host" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_HOST_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_host' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_host { echo "$as_me:$LINENO: checking for ut_host field in utmpx.h" >&5 echo $ECHO_N "checking for ut_host field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_host" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_HOST_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'syslen' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"syslen { echo "$as_me:$LINENO: checking for syslen field in utmpx.h" >&5 echo $ECHO_N "checking for syslen field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "syslen" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYSLEN_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_pid' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_pid { echo "$as_me:$LINENO: checking for ut_pid field in utmp.h" >&5 echo $ECHO_N "checking for ut_pid field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_pid" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_PID_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_type' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type { echo "$as_me:$LINENO: checking for ut_type field in utmp.h" >&5 echo $ECHO_N "checking for ut_type field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_type" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_type' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_type { echo "$as_me:$LINENO: checking for ut_type field in utmpx.h" >&5 echo $ECHO_N "checking for ut_type field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_type" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_tv' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv { echo "$as_me:$LINENO: checking for ut_tv field in utmp.h" >&5 echo $ECHO_N "checking for ut_tv field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_tv" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TV_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_id' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id { echo "$as_me:$LINENO: checking for ut_id field in utmp.h" >&5 echo $ECHO_N "checking for ut_id field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_id" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ID_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_id' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_id { echo "$as_me:$LINENO: checking for ut_id field in utmpx.h" >&5 echo $ECHO_N "checking for ut_id field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_id" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ID_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_addr' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr { echo "$as_me:$LINENO: checking for ut_addr field in utmp.h" >&5 echo $ECHO_N "checking for ut_addr field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_addr" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ADDR_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_addr' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr { echo "$as_me:$LINENO: checking for ut_addr field in utmpx.h" >&5 echo $ECHO_N "checking for ut_addr field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_addr" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ADDR_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_addr_v6' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 { echo "$as_me:$LINENO: checking for ut_addr_v6 field in utmp.h" >&5 echo $ECHO_N "checking for ut_addr_v6 field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_addr_v6" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ADDR_V6_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_addr_v6' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_addr_v6 { echo "$as_me:$LINENO: checking for ut_addr_v6 field in utmpx.h" >&5 echo $ECHO_N "checking for ut_addr_v6 field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_addr_v6" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ADDR_V6_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_exit' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_exit { echo "$as_me:$LINENO: checking for ut_exit field in utmp.h" >&5 echo $ECHO_N "checking for ut_exit field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_exit" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_EXIT_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_time' in header 'utmp.h' ossh_safe=`echo "utmp.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time { echo "$as_me:$LINENO: checking for ut_time field in utmp.h" >&5 echo $ECHO_N "checking for ut_time field in utmp.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_time" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TIME_IN_UTMP 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_time' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_time { echo "$as_me:$LINENO: checking for ut_time field in utmpx.h" >&5 echo $ECHO_N "checking for ut_time field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_time" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TIME_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # look for field 'ut_tv' in header 'utmpx.h' ossh_safe=`echo "utmpx.h" | sed 'y%./+-%__p_%'` ossh_varname="ossh_cv_$ossh_safe""_has_"ut_tv { echo "$as_me:$LINENO: checking for ut_tv field in utmpx.h" >&5 echo $ECHO_N "checking for ut_tv field in utmpx.h... $ECHO_C" >&6; } if { as_var=$ossh_varname; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ut_tv" >/dev/null 2>&1; then eval "$ossh_varname=yes" else eval "$ossh_varname=no" fi rm -f conftest* fi ossh_result=`eval 'echo $'"$ossh_varname"` if test -n "`echo $ossh_varname`"; then { echo "$as_me:$LINENO: result: $ossh_result" >&5 echo "${ECHO_T}$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TV_IN_UTMPX 1 _ACEOF fi else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi { echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5 echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6; } if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static struct stat ac_aggr; if (ac_aggr.st_blksize) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_stat_st_blksize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static struct stat ac_aggr; if (sizeof ac_aggr.st_blksize) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_stat_st_blksize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_stat_st_blksize=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5 echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6; } if test $ac_cv_member_struct_stat_st_blksize = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct passwd.pw_gecos" >&5 echo $ECHO_N "checking for struct passwd.pw_gecos... $ECHO_C" >&6; } if test "${ac_cv_member_struct_passwd_pw_gecos+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (ac_aggr.pw_gecos) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_gecos=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (sizeof ac_aggr.pw_gecos) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_gecos=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_passwd_pw_gecos=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_passwd_pw_gecos" >&5 echo "${ECHO_T}$ac_cv_member_struct_passwd_pw_gecos" >&6; } if test $ac_cv_member_struct_passwd_pw_gecos = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_GECOS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct passwd.pw_class" >&5 echo $ECHO_N "checking for struct passwd.pw_class... $ECHO_C" >&6; } if test "${ac_cv_member_struct_passwd_pw_class+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (ac_aggr.pw_class) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_class=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (sizeof ac_aggr.pw_class) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_class=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_passwd_pw_class=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_passwd_pw_class" >&5 echo "${ECHO_T}$ac_cv_member_struct_passwd_pw_class" >&6; } if test $ac_cv_member_struct_passwd_pw_class = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_CLASS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct passwd.pw_change" >&5 echo $ECHO_N "checking for struct passwd.pw_change... $ECHO_C" >&6; } if test "${ac_cv_member_struct_passwd_pw_change+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (ac_aggr.pw_change) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_change=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (sizeof ac_aggr.pw_change) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_change=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_passwd_pw_change=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_passwd_pw_change" >&5 echo "${ECHO_T}$ac_cv_member_struct_passwd_pw_change" >&6; } if test $ac_cv_member_struct_passwd_pw_change = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_CHANGE 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct passwd.pw_expire" >&5 echo $ECHO_N "checking for struct passwd.pw_expire... $ECHO_C" >&6; } if test "${ac_cv_member_struct_passwd_pw_expire+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (ac_aggr.pw_expire) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_expire=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { static struct passwd ac_aggr; if (sizeof ac_aggr.pw_expire) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_passwd_pw_expire=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_passwd_pw_expire=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_passwd_pw_expire" >&5 echo "${ECHO_T}$ac_cv_member_struct_passwd_pw_expire" >&6; } if test $ac_cv_member_struct_passwd_pw_expire = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_EXPIRE 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct __res_state.retrans" >&5 echo $ECHO_N "checking for struct __res_state.retrans... $ECHO_C" >&6; } if test "${ac_cv_member_struct___res_state_retrans+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include int main () { static struct __res_state ac_aggr; if (ac_aggr.retrans) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct___res_state_retrans=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include int main () { static struct __res_state ac_aggr; if (sizeof ac_aggr.retrans) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct___res_state_retrans=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct___res_state_retrans=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct___res_state_retrans" >&5 echo "${ECHO_T}$ac_cv_member_struct___res_state_retrans" >&6; } if test $ac_cv_member_struct___res_state_retrans = yes; then : else cat >>confdefs.h <<\_ACEOF #define __res_state state _ACEOF fi { echo "$as_me:$LINENO: checking for ss_family field in struct sockaddr_storage" >&5 echo $ECHO_N "checking for ss_family field in struct sockaddr_storage... $ECHO_C" >&6; } if test "${ac_cv_have_ss_family_in_struct_ss+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; s.ss_family = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_ss_family_in_struct_ss="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_ss_family_in_struct_ss="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_ss_family_in_struct_ss" >&5 echo "${ECHO_T}$ac_cv_have_ss_family_in_struct_ss" >&6; } if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SS_FAMILY_IN_SS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for __ss_family field in struct sockaddr_storage" >&5 echo $ECHO_N "checking for __ss_family field in struct sockaddr_storage... $ECHO_C" >&6; } if test "${ac_cv_have___ss_family_in_struct_ss+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; s.__ss_family = 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have___ss_family_in_struct_ss="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have___ss_family_in_struct_ss="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have___ss_family_in_struct_ss" >&5 echo "${ECHO_T}$ac_cv_have___ss_family_in_struct_ss" >&6; } if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE___SS_FAMILY_IN_SS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for msg_accrights field in struct msghdr" >&5 echo $ECHO_N "checking for msg_accrights field in struct msghdr... $ECHO_C" >&6; } if test "${ac_cv_have_accrights_in_msghdr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { #ifdef msg_accrights #error "msg_accrights is a macro" exit(1); #endif struct msghdr m; m.msg_accrights = 0; exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_accrights_in_msghdr="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_accrights_in_msghdr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_accrights_in_msghdr" >&5 echo "${ECHO_T}$ac_cv_have_accrights_in_msghdr" >&6; } if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ACCRIGHTS_IN_MSGHDR 1 _ACEOF fi { echo "$as_me:$LINENO: checking if struct statvfs.f_fsid is integral type" >&5 echo $ECHO_N "checking if struct statvfs.f_fsid is integral type... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif int main () { struct statvfs s; s.f_fsid = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { echo "$as_me:$LINENO: checking if fsid_t has member val" >&5 echo $ECHO_N "checking if fsid_t has member val... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { fsid_t t; t.val[0] = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define FSID_HAS_VAL 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: checking if f_fsid has member __val" >&5 echo $ECHO_N "checking if f_fsid has member __val... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { fsid_t t; t.__val[0] = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define FSID_HAS___VAL 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: checking for msg_control field in struct msghdr" >&5 echo $ECHO_N "checking for msg_control field in struct msghdr... $ECHO_C" >&6; } if test "${ac_cv_have_control_in_msghdr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { #ifdef msg_control #error "msg_control is a macro" exit(1); #endif struct msghdr m; m.msg_control = 0; exit(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_control_in_msghdr="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_control_in_msghdr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_control_in_msghdr" >&5 echo "${ECHO_T}$ac_cv_have_control_in_msghdr" >&6; } if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_CONTROL_IN_MSGHDR 1 _ACEOF fi { echo "$as_me:$LINENO: checking if libc defines __progname" >&5 echo $ECHO_N "checking if libc defines __progname... $ECHO_C" >&6; } if test "${ac_cv_libc_defines___progname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern char *__progname; printf("%s", __progname); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_libc_defines___progname="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_libc_defines___progname="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_libc_defines___progname" >&5 echo "${ECHO_T}$ac_cv_libc_defines___progname" >&6; } if test "x$ac_cv_libc_defines___progname" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE___PROGNAME 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether $CC implements __FUNCTION__" >&5 echo $ECHO_N "checking whether $CC implements __FUNCTION__... $ECHO_C" >&6; } if test "${ac_cv_cc_implements___FUNCTION__+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { printf("%s", __FUNCTION__); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_cc_implements___FUNCTION__="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_cc_implements___FUNCTION__="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_cc_implements___FUNCTION__" >&5 echo "${ECHO_T}$ac_cv_cc_implements___FUNCTION__" >&6; } if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE___FUNCTION__ 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether $CC implements __func__" >&5 echo $ECHO_N "checking whether $CC implements __func__... $ECHO_C" >&6; } if test "${ac_cv_cc_implements___func__+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { printf("%s", __func__); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_cc_implements___func__="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_cc_implements___func__="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_cc_implements___func__" >&5 echo "${ECHO_T}$ac_cv_cc_implements___func__" >&6; } if test "x$ac_cv_cc_implements___func__" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE___func__ 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether va_copy exists" >&5 echo $ECHO_N "checking whether va_copy exists... $ECHO_C" >&6; } if test "${ac_cv_have_va_copy+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include va_list x,y; int main () { va_copy(x,y); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_have_va_copy="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_va_copy="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_va_copy" >&5 echo "${ECHO_T}$ac_cv_have_va_copy" >&6; } if test "x$ac_cv_have_va_copy" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_VA_COPY 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether __va_copy exists" >&5 echo $ECHO_N "checking whether __va_copy exists... $ECHO_C" >&6; } if test "${ac_cv_have___va_copy+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include va_list x,y; int main () { __va_copy(x,y); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_have___va_copy="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have___va_copy="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have___va_copy" >&5 echo "${ECHO_T}$ac_cv_have___va_copy" >&6; } if test "x$ac_cv_have___va_copy" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE___VA_COPY 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether getopt has optreset support" >&5 echo $ECHO_N "checking whether getopt has optreset support... $ECHO_C" >&6; } if test "${ac_cv_have_getopt_optreset+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { extern int optreset; optreset = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_have_getopt_optreset="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_getopt_optreset="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_getopt_optreset" >&5 echo "${ECHO_T}$ac_cv_have_getopt_optreset" >&6; } if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_GETOPT_OPTRESET 1 _ACEOF fi { echo "$as_me:$LINENO: checking if libc defines sys_errlist" >&5 echo $ECHO_N "checking if libc defines sys_errlist... $ECHO_C" >&6; } if test "${ac_cv_libc_defines_sys_errlist+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_libc_defines_sys_errlist="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_libc_defines_sys_errlist="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_libc_defines_sys_errlist" >&5 echo "${ECHO_T}$ac_cv_libc_defines_sys_errlist" >&6; } if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_ERRLIST 1 _ACEOF fi { echo "$as_me:$LINENO: checking if libc defines sys_nerr" >&5 echo $ECHO_N "checking if libc defines sys_nerr... $ECHO_C" >&6; } if test "${ac_cv_libc_defines_sys_nerr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern int sys_nerr; printf("%i", sys_nerr); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_libc_defines_sys_nerr="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_libc_defines_sys_nerr="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_libc_defines_sys_nerr" >&5 echo "${ECHO_T}$ac_cv_libc_defines_sys_nerr" >&6; } if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_NERR 1 _ACEOF fi # Check libraries needed by DNS fingerprint support { echo "$as_me:$LINENO: checking for library containing getrrsetbyname" >&5 echo $ECHO_N "checking for library containing getrrsetbyname... $ECHO_C" >&6; } if test "${ac_cv_search_getrrsetbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getrrsetbyname (); int main () { return getrrsetbyname (); ; return 0; } _ACEOF for ac_lib in '' resolv; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_getrrsetbyname=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_getrrsetbyname+set}" = set; then break fi done if test "${ac_cv_search_getrrsetbyname+set}" = set; then : else ac_cv_search_getrrsetbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_getrrsetbyname" >&5 echo "${ECHO_T}$ac_cv_search_getrrsetbyname" >&6; } ac_res=$ac_cv_search_getrrsetbyname if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define HAVE_GETRRSETBYNAME 1 _ACEOF else # Needed by our getrrsetbyname() { echo "$as_me:$LINENO: checking for library containing res_query" >&5 echo $ECHO_N "checking for library containing res_query... $ECHO_C" >&6; } if test "${ac_cv_search_res_query+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char res_query (); int main () { return res_query (); ; return 0; } _ACEOF for ac_lib in '' resolv; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_res_query=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_res_query+set}" = set; then break fi done if test "${ac_cv_search_res_query+set}" = set; then : else ac_cv_search_res_query=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_res_query" >&5 echo "${ECHO_T}$ac_cv_search_res_query" >&6; } ac_res=$ac_cv_search_res_query if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing dn_expand" >&5 echo $ECHO_N "checking for library containing dn_expand... $ECHO_C" >&6; } if test "${ac_cv_search_dn_expand+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dn_expand (); int main () { return dn_expand (); ; return 0; } _ACEOF for ac_lib in '' resolv; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_dn_expand=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dn_expand+set}" = set; then break fi done if test "${ac_cv_search_dn_expand+set}" = set; then : else ac_cv_search_dn_expand=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_dn_expand" >&5 echo "${ECHO_T}$ac_cv_search_dn_expand" >&6; } ac_res=$ac_cv_search_dn_expand if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking if res_query will link" >&5 echo $ECHO_N "checking if res_query will link... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include int main () { res_query (0, 0, 0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } saved_LIBS="$LIBS" LIBS="$LIBS -lresolv" { echo "$as_me:$LINENO: checking for res_query in -lresolv" >&5 echo $ECHO_N "checking for res_query in -lresolv... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include #include int main () { res_query (0, 0, 0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS="$saved_LIBS" { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext for ac_func in _getshort _getlong do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether _getshort is declared" >&5 echo $ECHO_N "checking whether _getshort is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl__getshort+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _getshort (void) _getshort; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl__getshort=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl__getshort=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl__getshort" >&5 echo "${ECHO_T}$ac_cv_have_decl__getshort" >&6; } if test $ac_cv_have_decl__getshort = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETSHORT 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETSHORT 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether _getlong is declared" >&5 echo $ECHO_N "checking whether _getlong is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl__getlong+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _getlong (void) _getlong; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl__getlong=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl__getlong=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl__getlong" >&5 echo "${ECHO_T}$ac_cv_have_decl__getlong" >&6; } if test $ac_cv_have_decl__getlong = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETLONG 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETLONG 0 _ACEOF fi { echo "$as_me:$LINENO: checking for HEADER.ad" >&5 echo $ECHO_N "checking for HEADER.ad... $ECHO_C" >&6; } if test "${ac_cv_member_HEADER_ad+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { static HEADER ac_aggr; if (ac_aggr.ad) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_HEADER_ad=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { static HEADER ac_aggr; if (sizeof ac_aggr.ad) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_HEADER_ad=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_HEADER_ad=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_HEADER_ad" >&5 echo "${ECHO_T}$ac_cv_member_HEADER_ad" >&6; } if test $ac_cv_member_HEADER_ad = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_HEADER_AD 1 _ACEOF fi fi { echo "$as_me:$LINENO: checking if struct __res_state _res is an extern" >&5 echo $ECHO_N "checking if struct __res_state _res is an extern... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include extern struct __res_state _res; int main () { struct __res_state *volatile p = &_res; /* force resolution of _res */ return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE__RES_EXTERN 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Check whether user wants SELinux support SELINUX_MSG="no" LIBSELINUX="" # Check whether --with-selinux was given. if test "${with_selinux+set}" = set; then withval=$with_selinux; if test "x$withval" != "xno" ; then save_LIBS="$LIBS" cat >>confdefs.h <<\_ACEOF #define WITH_SELINUX 1 _ACEOF SELINUX_MSG="yes" if test "${ac_cv_header_selinux_selinux_h+set}" = set; then { echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 echo $ECHO_N "checking for selinux/selinux.h... $ECHO_C" >&6; } if test "${ac_cv_header_selinux_selinux_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 echo "${ECHO_T}$ac_cv_header_selinux_selinux_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking selinux/selinux.h usability" >&5 echo $ECHO_N "checking selinux/selinux.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking selinux/selinux.h presence" >&5 echo $ECHO_N "checking selinux/selinux.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: selinux/selinux.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: selinux/selinux.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: selinux/selinux.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: selinux/selinux.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: selinux/selinux.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: selinux/selinux.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: selinux/selinux.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: selinux/selinux.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for selinux/selinux.h" >&5 echo $ECHO_N "checking for selinux/selinux.h... $ECHO_C" >&6; } if test "${ac_cv_header_selinux_selinux_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_selinux_selinux_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_selinux_selinux_h" >&5 echo "${ECHO_T}$ac_cv_header_selinux_selinux_h" >&6; } fi if test $ac_cv_header_selinux_selinux_h = yes; then : else { { echo "$as_me:$LINENO: error: SELinux support requires selinux.h header" >&5 echo "$as_me: error: SELinux support requires selinux.h header" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for setexeccon in -lselinux" >&5 echo $ECHO_N "checking for setexeccon in -lselinux... $ECHO_C" >&6; } if test "${ac_cv_lib_selinux_setexeccon+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lselinux $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setexeccon (); int main () { return setexeccon (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_selinux_setexeccon=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_selinux_setexeccon=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_setexeccon" >&5 echo "${ECHO_T}$ac_cv_lib_selinux_setexeccon" >&6; } if test $ac_cv_lib_selinux_setexeccon = yes; then LIBSELINUX="-lselinux" LIBS="$LIBS -lselinux" else { { echo "$as_me:$LINENO: error: SELinux support requires libselinux library" >&5 echo "$as_me: error: SELinux support requires libselinux library" >&2;} { (exit 1); exit 1; }; } fi SSHLIBS="$SSHLIBS $LIBSELINUX" SSHDLIBS="$SSHDLIBS $LIBSELINUX" for ac_func in getseuserbyname get_default_context_with_level do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS="$save_LIBS" fi fi # Check whether user wants Kerberos 5 support KRB5_MSG="no" # Check whether --with-kerberos5 was given. if test "${with_kerberos5+set}" = set; then withval=$with_kerberos5; if test "x$withval" != "xno" ; then if test "x$withval" = "xyes" ; then KRB5ROOT="/usr/local" else KRB5ROOT=${withval} fi cat >>confdefs.h <<\_ACEOF #define KRB5 1 _ACEOF KRB5_MSG="yes" # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_KRB5CONF+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $KRB5CONF in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5CONF="$KRB5CONF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$KRB5ROOT/bin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_KRB5CONF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_KRB5CONF" && ac_cv_path_KRB5CONF="$KRB5ROOT/bin/krb5-config" ;; esac fi KRB5CONF=$ac_cv_path_KRB5CONF if test -n "$KRB5CONF"; then { echo "$as_me:$LINENO: result: $KRB5CONF" >&5 echo "${ECHO_T}$KRB5CONF" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -x $KRB5CONF ; then K5CFLAGS="`$KRB5CONF --cflags`" K5LIBS="`$KRB5CONF --libs`" CPPFLAGS="$CPPFLAGS $K5CFLAGS" { echo "$as_me:$LINENO: checking for gssapi support" >&5 echo $ECHO_N "checking for gssapi support... $ECHO_C" >&6; } if $KRB5CONF | grep gssapi >/dev/null ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define GSSAPI 1 _ACEOF GSSCFLAGS="`$KRB5CONF --cflags gssapi`" GSSLIBS="`$KRB5CONF --libs gssapi`" CPPFLAGS="$CPPFLAGS $GSSCFLAGS" else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi { echo "$as_me:$LINENO: checking whether we are using Heimdal" >&5 echo $ECHO_N "checking whether we are using Heimdal... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *tmp = heimdal_version; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HEIMDAL 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include" LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib" { echo "$as_me:$LINENO: checking whether we are using Heimdal" >&5 echo $ECHO_N "checking whether we are using Heimdal... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *tmp = heimdal_version; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HEIMDAL 1 _ACEOF K5LIBS="-lkrb5" K5LIBS="$K5LIBS -lcom_err -lasn1" { echo "$as_me:$LINENO: checking for net_write in -lroken" >&5 echo $ECHO_N "checking for net_write in -lroken... $ECHO_C" >&6; } if test "${ac_cv_lib_roken_net_write+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lroken $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char net_write (); int main () { return net_write (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_roken_net_write=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_roken_net_write=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_roken_net_write" >&5 echo "${ECHO_T}$ac_cv_lib_roken_net_write" >&6; } if test $ac_cv_lib_roken_net_write = yes; then K5LIBS="$K5LIBS -lroken" fi { echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes" >&5 echo $ECHO_N "checking for des_cbc_encrypt in -ldes... $ECHO_C" >&6; } if test "${ac_cv_lib_des_des_cbc_encrypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldes $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char des_cbc_encrypt (); int main () { return des_cbc_encrypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_des_des_cbc_encrypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_des_des_cbc_encrypt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_des_des_cbc_encrypt" >&5 echo "${ECHO_T}$ac_cv_lib_des_des_cbc_encrypt" >&6; } if test $ac_cv_lib_des_des_cbc_encrypt = yes; then K5LIBS="$K5LIBS -ldes" fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } K5LIBS="-lkrb5 -lk5crypto -lcom_err" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: checking for library containing dn_expand" >&5 echo $ECHO_N "checking for library containing dn_expand... $ECHO_C" >&6; } if test "${ac_cv_search_dn_expand+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dn_expand (); int main () { return dn_expand (); ; return 0; } _ACEOF for ac_lib in '' resolv; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_dn_expand=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dn_expand+set}" = set; then break fi done if test "${ac_cv_search_dn_expand+set}" = set; then : else ac_cv_search_dn_expand=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_dn_expand" >&5 echo "${ECHO_T}$ac_cv_search_dn_expand" >&6; } ac_res=$ac_cv_search_dn_expand if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi_krb5" >&5 echo $ECHO_N "checking for gss_init_sec_context in -lgssapi_krb5... $ECHO_C" >&6; } if test "${ac_cv_lib_gssapi_krb5_gss_init_sec_context+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgssapi_krb5 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gss_init_sec_context (); int main () { return gss_init_sec_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gssapi_krb5_gss_init_sec_context=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gssapi_krb5_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&5 echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&6; } if test $ac_cv_lib_gssapi_krb5_gss_init_sec_context = yes; then cat >>confdefs.h <<\_ACEOF #define GSSAPI 1 _ACEOF GSSLIBS="-lgssapi_krb5" else { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi" >&5 echo $ECHO_N "checking for gss_init_sec_context in -lgssapi... $ECHO_C" >&6; } if test "${ac_cv_lib_gssapi_gss_init_sec_context+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgssapi $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gss_init_sec_context (); int main () { return gss_init_sec_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gssapi_gss_init_sec_context=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gssapi_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_init_sec_context" >&5 echo "${ECHO_T}$ac_cv_lib_gssapi_gss_init_sec_context" >&6; } if test $ac_cv_lib_gssapi_gss_init_sec_context = yes; then cat >>confdefs.h <<\_ACEOF #define GSSAPI 1 _ACEOF GSSLIBS="-lgssapi" else { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgss" >&5 echo $ECHO_N "checking for gss_init_sec_context in -lgss... $ECHO_C" >&6; } if test "${ac_cv_lib_gss_gss_init_sec_context+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgss $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gss_init_sec_context (); int main () { return gss_init_sec_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gss_gss_init_sec_context=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gss_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gss_gss_init_sec_context" >&5 echo "${ECHO_T}$ac_cv_lib_gss_gss_init_sec_context" >&6; } if test $ac_cv_lib_gss_gss_init_sec_context = yes; then cat >>confdefs.h <<\_ACEOF #define GSSAPI 1 _ACEOF GSSLIBS="-lgss" else { echo "$as_me:$LINENO: WARNING: Cannot find any suitable gss-api library - build may fail" >&5 echo "$as_me: WARNING: Cannot find any suitable gss-api library - build may fail" >&2;} fi fi fi if test "${ac_cv_header_gssapi_h+set}" = set; then { echo "$as_me:$LINENO: checking for gssapi.h" >&5 echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6; } if test "${ac_cv_header_gssapi_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5 echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking gssapi.h usability" >&5 echo $ECHO_N "checking gssapi.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking gssapi.h presence" >&5 echo $ECHO_N "checking gssapi.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: gssapi.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: gssapi.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: gssapi.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: gssapi.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: gssapi.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: gssapi.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: gssapi.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: gssapi.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for gssapi.h" >&5 echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6; } if test "${ac_cv_header_gssapi_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_gssapi_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5 echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6; } fi if test $ac_cv_header_gssapi_h = yes; then : else unset ac_cv_header_gssapi_h CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" for ac_header in gssapi.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else { echo "$as_me:$LINENO: WARNING: Cannot find any suitable gss-api header - build may fail" >&5 echo "$as_me: WARNING: Cannot find any suitable gss-api header - build may fail" >&2;} fi done fi oldCPP="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" if test "${ac_cv_header_gssapi_krb5_h+set}" = set; then { echo "$as_me:$LINENO: checking for gssapi_krb5.h" >&5 echo $ECHO_N "checking for gssapi_krb5.h... $ECHO_C" >&6; } if test "${ac_cv_header_gssapi_krb5_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_krb5_h" >&5 echo "${ECHO_T}$ac_cv_header_gssapi_krb5_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking gssapi_krb5.h usability" >&5 echo $ECHO_N "checking gssapi_krb5.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking gssapi_krb5.h presence" >&5 echo $ECHO_N "checking gssapi_krb5.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: gssapi_krb5.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: gssapi_krb5.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: gssapi_krb5.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: gssapi_krb5.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: gssapi_krb5.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: gssapi_krb5.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: gssapi_krb5.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: gssapi_krb5.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: gssapi_krb5.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for gssapi_krb5.h" >&5 echo $ECHO_N "checking for gssapi_krb5.h... $ECHO_C" >&6; } if test "${ac_cv_header_gssapi_krb5_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_gssapi_krb5_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_krb5_h" >&5 echo "${ECHO_T}$ac_cv_header_gssapi_krb5_h" >&6; } fi if test $ac_cv_header_gssapi_krb5_h = yes; then : else CPPFLAGS="$oldCPP" fi fi if test ! -z "$need_dash_r" ; then LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" fi if test ! -z "$blibpath" ; then blibpath="$blibpath:${KRB5ROOT}/lib" fi for ac_header in gssapi.h gssapi/gssapi.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in gssapi_krb5.h gssapi/gssapi_krb5.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in gssapi_generic.h gssapi/gssapi_generic.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for library containing k_hasafs" >&5 echo $ECHO_N "checking for library containing k_hasafs... $ECHO_C" >&6; } if test "${ac_cv_search_k_hasafs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char k_hasafs (); int main () { return k_hasafs (); ; return 0; } _ACEOF for ac_lib in '' kafs; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_k_hasafs=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_k_hasafs+set}" = set; then break fi done if test "${ac_cv_search_k_hasafs+set}" = set; then : else ac_cv_search_k_hasafs=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_k_hasafs" >&5 echo "${ECHO_T}$ac_cv_search_k_hasafs" >&6; } ac_res=$ac_cv_search_k_hasafs if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" cat >>confdefs.h <<\_ACEOF #define USE_AFS 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether GSS_C_NT_HOSTBASED_SERVICE is declared" >&5 echo $ECHO_N "checking whether GSS_C_NT_HOSTBASED_SERVICE is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_GSSAPI_H # include #elif defined(HAVE_GSSAPI_GSSAPI_H) # include #endif #ifdef HAVE_GSSAPI_GENERIC_H # include #elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) # include #endif int main () { #ifndef GSS_C_NT_HOSTBASED_SERVICE (void) GSS_C_NT_HOSTBASED_SERVICE; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE" >&5 echo "${ECHO_T}$ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE" >&6; } if test $ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE 0 _ACEOF fi saved_LIBS="$LIBS" LIBS="$LIBS $K5LIBS" for ac_func in krb5_cc_new_unique krb5_get_error_message krb5_free_error_message do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS="$saved_LIBS" fi fi # Looking for programs, paths and files PRIVSEP_PATH=/var/empty # Check whether --with-privsep-path was given. if test "${with_privsep_path+set}" = set; then withval=$with_privsep_path; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then PRIVSEP_PATH=$withval fi fi # Check whether --with-xauth was given. if test "${with_xauth+set}" = set; then withval=$with_xauth; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then xauth_path=$withval fi else TestPath="$PATH" TestPath="${TestPath}${PATH_SEPARATOR}/usr/X/bin" TestPath="${TestPath}${PATH_SEPARATOR}/usr/bin/X11" TestPath="${TestPath}${PATH_SEPARATOR}/usr/X11R6/bin" TestPath="${TestPath}${PATH_SEPARATOR}/usr/openwin/bin" # Extract the first word of "xauth", so it can be a program name with args. set dummy xauth; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_xauth_path+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $xauth_path in [\\/]* | ?:[\\/]*) ac_cv_path_xauth_path="$xauth_path" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $TestPath do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_xauth_path="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi xauth_path=$ac_cv_path_xauth_path if test -n "$xauth_path"; then { echo "$as_me:$LINENO: result: $xauth_path" >&5 echo "${ECHO_T}$xauth_path" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then xauth_path="/usr/openwin/bin/xauth" fi fi STRIP_OPT=-s # Check whether --enable-strip was given. if test "${enable_strip+set}" = set; then enableval=$enable_strip; if test "x$enableval" = "xno" ; then STRIP_OPT= fi fi if test -z "$xauth_path" ; then XAUTH_PATH="undefined" else cat >>confdefs.h <<_ACEOF #define XAUTH_PATH "$xauth_path" _ACEOF XAUTH_PATH=$xauth_path fi # Check for mail directory # Check whether --with-maildir was given. if test "${with_maildir+set}" = set; then withval=$with_maildir; if test "X$withval" != X && test "x$withval" != xno && \ test "x${withval}" != xyes; then cat >>confdefs.h <<_ACEOF #define MAIL_DIRECTORY "$withval" _ACEOF fi else if test "X$maildir" != "X"; then cat >>confdefs.h <<_ACEOF #define MAIL_DIRECTORY "$maildir" _ACEOF else { echo "$as_me:$LINENO: checking Discovering system mail directory" >&5 echo $ECHO_N "checking Discovering system mail directory... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: WARNING: cross compiling: use --with-maildir=/path/to/mail" >&5 echo "$as_me: WARNING: cross compiling: use --with-maildir=/path/to/mail" >&2;} else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_PATHS_H #include #endif #ifdef HAVE_MAILLOCK_H #include #endif #define DATA "conftest.maildir" int main () { FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); #if defined (_PATH_MAILDIR) if ((rc = fprintf(fd ,"_PATH_MAILDIR:%s\n", _PATH_MAILDIR)) <0) exit(1); #elif defined (MAILDIR) if ((rc = fprintf(fd ,"MAILDIR:%s\n", MAILDIR)) <0) exit(1); #elif defined (_PATH_MAIL) if ((rc = fprintf(fd ,"_PATH_MAIL:%s\n", _PATH_MAIL)) <0) exit(1); #else exit (2); #endif exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then maildir_what=`awk -F: '{print $1}' conftest.maildir` maildir=`awk -F: '{print $2}' conftest.maildir \ | sed 's|/$||'` { echo "$as_me:$LINENO: result: Using: $maildir from $maildir_what" >&5 echo "${ECHO_T}Using: $maildir from $maildir_what" >&6; } if test "x$maildir_what" != "x_PATH_MAILDIR"; then cat >>confdefs.h <<_ACEOF #define MAIL_DIRECTORY "$maildir" _ACEOF fi else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "X$ac_status" = "X2";then # our test program didn't find it. Default to /var/spool/mail { echo "$as_me:$LINENO: result: Using: default value of /var/spool/mail" >&5 echo "${ECHO_T}Using: default value of /var/spool/mail" >&6; } cat >>confdefs.h <<_ACEOF #define MAIL_DIRECTORY "/var/spool/mail" _ACEOF else { echo "$as_me:$LINENO: result: *** not found ***" >&5 echo "${ECHO_T}*** not found ***" >&6; } fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi # maildir if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then { echo "$as_me:$LINENO: WARNING: cross compiling: Disabling /dev/ptmx test" >&5 echo "$as_me: WARNING: cross compiling: Disabling /dev/ptmx test" >&2;} disable_ptmx_check=yes fi if test -z "$no_dev_ptmx" ; then if test "x$disable_ptmx_check" != "xyes" ; then { echo "$as_me:$LINENO: checking for \"/dev/ptmx\"" >&5 echo $ECHO_N "checking for \"/dev/ptmx\"... $ECHO_C" >&6; } if test "${ac_cv_file___dev_ptmx_+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else test "$cross_compiling" = yes && { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} { (exit 1); exit 1; }; } if test -r ""/dev/ptmx""; then ac_cv_file___dev_ptmx_=yes else ac_cv_file___dev_ptmx_=no fi fi { echo "$as_me:$LINENO: result: $ac_cv_file___dev_ptmx_" >&5 echo "${ECHO_T}$ac_cv_file___dev_ptmx_" >&6; } if test $ac_cv_file___dev_ptmx_ = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DEV_PTMX 1 _ACEOF have_dev_ptmx=1 fi fi fi if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then { echo "$as_me:$LINENO: checking for \"/dev/ptc\"" >&5 echo $ECHO_N "checking for \"/dev/ptc\"... $ECHO_C" >&6; } if test "${ac_cv_file___dev_ptc_+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else test "$cross_compiling" = yes && { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} { (exit 1); exit 1; }; } if test -r ""/dev/ptc""; then ac_cv_file___dev_ptc_=yes else ac_cv_file___dev_ptc_=no fi fi { echo "$as_me:$LINENO: result: $ac_cv_file___dev_ptc_" >&5 echo "${ECHO_T}$ac_cv_file___dev_ptc_" >&6; } if test $ac_cv_file___dev_ptc_ = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DEV_PTS_AND_PTC 1 _ACEOF have_dev_ptc=1 fi else { echo "$as_me:$LINENO: WARNING: cross compiling: Disabling /dev/ptc test" >&5 echo "$as_me: WARNING: cross compiling: Disabling /dev/ptc test" >&2;} fi # Options from here on. Some of these are preset by platform above # Check whether --with-mantype was given. if test "${with_mantype+set}" = set; then withval=$with_mantype; case "$withval" in man|cat|doc) MANTYPE=$withval ;; *) { { echo "$as_me:$LINENO: error: invalid man type: $withval" >&5 echo "$as_me: error: invalid man type: $withval" >&2;} { (exit 1); exit 1; }; } ;; esac fi if test -z "$MANTYPE"; then TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb" for ac_prog in nroff awf do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_NROFF+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $NROFF in [\\/]* | ?:[\\/]*) ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $TestPath do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi NROFF=$ac_cv_path_NROFF if test -n "$NROFF"; then { echo "$as_me:$LINENO: result: $NROFF" >&5 echo "${ECHO_T}$NROFF" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$NROFF" && break done test -n "$NROFF" || NROFF="/bin/false" if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then MANTYPE=doc elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then MANTYPE=man else MANTYPE=cat fi fi if test "$MANTYPE" = "doc"; then mansubdir=man; else mansubdir=$MANTYPE; fi # Check whether to enable MD5 passwords MD5_MSG="no" # Check whether --with-md5-passwords was given. if test "${with_md5_passwords+set}" = set; then withval=$with_md5_passwords; if test "x$withval" != "xno" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_MD5_PASSWORDS 1 _ACEOF MD5_MSG="yes" fi fi # Whether to disable shadow password support # Check whether --with-shadow was given. if test "${with_shadow+set}" = set; then withval=$with_shadow; if test "x$withval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_SHADOW 1 _ACEOF disable_shadow=yes fi fi if test -z "$disable_shadow" ; then { echo "$as_me:$LINENO: checking if the systems has expire shadow information" >&5 echo $ECHO_N "checking if the systems has expire shadow information... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include struct spwd sp; int main () { sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then sp_expire_available=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$sp_expire_available" = "xyes" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAS_SHADOW_EXPIRE 1 _ACEOF else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi # Use ip address instead of hostname in $DISPLAY if test ! -z "$IPADDR_IN_DISPLAY" ; then DISPLAY_HACK_MSG="yes" cat >>confdefs.h <<\_ACEOF #define IPADDR_IN_DISPLAY 1 _ACEOF else DISPLAY_HACK_MSG="no" # Check whether --with-ipaddr-display was given. if test "${with_ipaddr_display+set}" = set; then withval=$with_ipaddr_display; if test "x$withval" != "xno" ; then cat >>confdefs.h <<\_ACEOF #define IPADDR_IN_DISPLAY 1 _ACEOF DISPLAY_HACK_MSG="yes" fi fi fi # check for /etc/default/login and use it if present. # Check whether --enable-etc-default-login was given. if test "${enable_etc_default_login+set}" = set; then enableval=$enable_etc_default_login; if test "x$enableval" = "xno"; then { echo "$as_me:$LINENO: /etc/default/login handling disabled" >&5 echo "$as_me: /etc/default/login handling disabled" >&6;} etc_default_login=no else etc_default_login=yes fi else if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then { echo "$as_me:$LINENO: WARNING: cross compiling: not checking /etc/default/login" >&5 echo "$as_me: WARNING: cross compiling: not checking /etc/default/login" >&2;} etc_default_login=no else etc_default_login=yes fi fi if test "x$etc_default_login" != "xno"; then { echo "$as_me:$LINENO: checking for \"/etc/default/login\"" >&5 echo $ECHO_N "checking for \"/etc/default/login\"... $ECHO_C" >&6; } if test "${ac_cv_file___etc_default_login_+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else test "$cross_compiling" = yes && { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} { (exit 1); exit 1; }; } if test -r ""/etc/default/login""; then ac_cv_file___etc_default_login_=yes else ac_cv_file___etc_default_login_=no fi fi { echo "$as_me:$LINENO: result: $ac_cv_file___etc_default_login_" >&5 echo "${ECHO_T}$ac_cv_file___etc_default_login_" >&6; } if test $ac_cv_file___etc_default_login_ = yes; then external_path_file=/etc/default/login fi if test "x$external_path_file" = "x/etc/default/login"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ETC_DEFAULT_LOGIN 1 _ACEOF fi fi if test $ac_cv_func_login_getcapbool = "yes" && \ test $ac_cv_header_login_cap_h = "yes" ; then external_path_file=/etc/login.conf fi # Whether to mess with the default path SERVER_PATH_MSG="(default)" # Check whether --with-default-path was given. if test "${with_default_path+set}" = set; then withval=$with_default_path; if test "x$external_path_file" = "x/etc/login.conf" ; then { echo "$as_me:$LINENO: WARNING: --with-default-path=PATH has no effect on this system. Edit /etc/login.conf instead." >&5 echo "$as_me: WARNING: --with-default-path=PATH has no effect on this system. Edit /etc/login.conf instead." >&2;} elif test "x$withval" != "xno" ; then if test ! -z "$external_path_file" ; then { echo "$as_me:$LINENO: WARNING: --with-default-path=PATH will only be used if PATH is not defined in $external_path_file ." >&5 echo "$as_me: WARNING: --with-default-path=PATH will only be used if PATH is not defined in $external_path_file ." >&2;} fi user_path="$withval" SERVER_PATH_MSG="$withval" fi else if test "x$external_path_file" = "x/etc/login.conf" ; then { echo "$as_me:$LINENO: WARNING: Make sure the path to scp is in /etc/login.conf" >&5 echo "$as_me: WARNING: Make sure the path to scp is in /etc/login.conf" >&2;} else if test ! -z "$external_path_file" ; then { echo "$as_me:$LINENO: WARNING: If PATH is defined in $external_path_file, ensure the path to scp is included, otherwise scp will not work." >&5 echo "$as_me: WARNING: If PATH is defined in $external_path_file, ensure the path to scp is included, otherwise scp will not work." >&2;} fi if test "$cross_compiling" = yes; then user_path="/usr/bin:/bin:/usr/sbin:/sbin" else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* find out what STDPATH is */ #include #ifdef HAVE_PATHS_H # include #endif #ifndef _PATH_STDPATH # ifdef _PATH_USERPATH /* Irix */ # define _PATH_STDPATH _PATH_USERPATH # else # define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" # endif #endif #include #include #include #define DATA "conftest.stdpath" int main () { FILE *fd; int rc; fd = fopen(DATA,"w"); if(fd == NULL) exit(1); if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0) exit(1); exit(0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then user_path=`cat conftest.stdpath` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) user_path="/usr/bin:/bin:/usr/sbin:/sbin" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi # make sure $bindir is in USER_PATH so scp will work t_bindir="${bindir}" while echo "${t_bindir}" | egrep '\$\{|NONE/' >/dev/null 2>&1; do t_bindir=`eval echo ${t_bindir}` case $t_bindir in NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;; esac case $t_bindir in NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;; esac done echo $user_path | grep ":$t_bindir" > /dev/null 2>&1 if test $? -ne 0 ; then echo $user_path | grep "^$t_bindir" > /dev/null 2>&1 if test $? -ne 0 ; then user_path=$user_path:$t_bindir { echo "$as_me:$LINENO: result: Adding $t_bindir to USER_PATH so scp will work" >&5 echo "${ECHO_T}Adding $t_bindir to USER_PATH so scp will work" >&6; } fi fi fi fi if test "x$external_path_file" != "x/etc/login.conf" ; then cat >>confdefs.h <<_ACEOF #define USER_PATH "$user_path" _ACEOF fi # Set superuser path separately to user path # Check whether --with-superuser-path was given. if test "${with_superuser_path+set}" = set; then withval=$with_superuser_path; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then cat >>confdefs.h <<_ACEOF #define SUPERUSER_PATH "$withval" _ACEOF superuser_path=$withval fi fi { echo "$as_me:$LINENO: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 echo $ECHO_N "checking if we need to convert IPv4 in IPv6-mapped addresses... $ECHO_C" >&6; } IPV4_IN6_HACK_MSG="no" # Check whether --with-4in6 was given. if test "${with_4in6+set}" = set; then withval=$with_4in6; if test "x$withval" != "xno" ; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF #define IPV4_IN_IPV6 1 _ACEOF IPV4_IN6_HACK_MSG="yes" else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi else if test "x$inet6_default_4in6" = "xyes"; then { echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6; } cat >>confdefs.h <<\_ACEOF #define IPV4_IN_IPV6 1 _ACEOF IPV4_IN6_HACK_MSG="yes" else { echo "$as_me:$LINENO: result: no (default)" >&5 echo "${ECHO_T}no (default)" >&6; } fi fi # Whether to enable BSD auth support BSD_AUTH_MSG=no # Check whether --with-bsd-auth was given. if test "${with_bsd_auth+set}" = set; then withval=$with_bsd_auth; if test "x$withval" != "xno" ; then cat >>confdefs.h <<\_ACEOF #define BSD_AUTH 1 _ACEOF BSD_AUTH_MSG=yes fi fi # Where to place sshd.pid piddir=/var/run # make sure the directory exists if test ! -d $piddir ; then piddir=`eval echo ${sysconfdir}` case $piddir in NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;; esac fi # Check whether --with-pid-dir was given. if test "${with_pid_dir+set}" = set; then withval=$with_pid_dir; if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then piddir=$withval if test ! -d $piddir ; then { echo "$as_me:$LINENO: WARNING: ** no $piddir directory on this system **" >&5 echo "$as_me: WARNING: ** no $piddir directory on this system **" >&2;} fi fi fi cat >>confdefs.h <<_ACEOF #define _PATH_SSH_PIDDIR "$piddir" _ACEOF # Check whether --enable-lastlog was given. if test "${enable_lastlog+set}" = set; then enableval=$enable_lastlog; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_LASTLOG 1 _ACEOF fi fi # Check whether --enable-utmp was given. if test "${enable_utmp+set}" = set; then enableval=$enable_utmp; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF fi fi # Check whether --enable-utmpx was given. if test "${enable_utmpx+set}" = set; then enableval=$enable_utmpx; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMPX 1 _ACEOF fi fi # Check whether --enable-wtmp was given. if test "${enable_wtmp+set}" = set; then enableval=$enable_wtmp; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMP 1 _ACEOF fi fi # Check whether --enable-wtmpx was given. if test "${enable_wtmpx+set}" = set; then enableval=$enable_wtmpx; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMPX 1 _ACEOF fi fi # Check whether --enable-libutil was given. if test "${enable_libutil+set}" = set; then enableval=$enable_libutil; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_LOGIN 1 _ACEOF fi fi # Check whether --enable-pututline was given. if test "${enable_pututline+set}" = set; then enableval=$enable_pututline; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_PUTUTLINE 1 _ACEOF fi fi # Check whether --enable-pututxline was given. if test "${enable_pututxline+set}" = set; then enableval=$enable_pututxline; if test "x$enableval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_PUTUTXLINE 1 _ACEOF fi fi # Check whether --with-lastlog was given. if test "${with_lastlog+set}" = set; then withval=$with_lastlog; if test "x$withval" = "xno" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_LASTLOG 1 _ACEOF elif test -n "$withval" && test "x${withval}" != "xyes"; then conf_lastlog_location=$withval fi fi { echo "$as_me:$LINENO: checking if your system defines LASTLOG_FILE" >&5 echo $ECHO_N "checking if your system defines LASTLOG_FILE... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_LASTLOG_H # include #endif #ifdef HAVE_PATHS_H # include #endif #ifdef HAVE_LOGIN_H # include #endif int main () { char *lastlog = LASTLOG_FILE; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { echo "$as_me:$LINENO: checking if your system defines _PATH_LASTLOG" >&5 echo $ECHO_N "checking if your system defines _PATH_LASTLOG... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_LASTLOG_H # include #endif #ifdef HAVE_PATHS_H # include #endif int main () { char *lastlog = _PATH_LASTLOG; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } system_lastlog_path=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test -z "$conf_lastlog_location"; then if test x"$system_lastlog_path" = x"no" ; then for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do if (test -d "$f" || test -f "$f") ; then conf_lastlog_location=$f fi done if test -z "$conf_lastlog_location"; then { echo "$as_me:$LINENO: WARNING: ** Cannot find lastlog **" >&5 echo "$as_me: WARNING: ** Cannot find lastlog **" >&2;} fi fi fi if test -n "$conf_lastlog_location"; then cat >>confdefs.h <<_ACEOF #define CONF_LASTLOG_FILE "$conf_lastlog_location" _ACEOF fi { echo "$as_me:$LINENO: checking if your system defines UTMP_FILE" >&5 echo $ECHO_N "checking if your system defines UTMP_FILE... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_PATHS_H # include #endif int main () { char *utmp = UTMP_FILE; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } system_utmp_path=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test -z "$conf_utmp_location"; then if test x"$system_utmp_path" = x"no" ; then for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do if test -f $f ; then conf_utmp_location=$f fi done if test -z "$conf_utmp_location"; then cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF fi fi fi if test -n "$conf_utmp_location"; then cat >>confdefs.h <<_ACEOF #define CONF_UTMP_FILE "$conf_utmp_location" _ACEOF fi { echo "$as_me:$LINENO: checking if your system defines WTMP_FILE" >&5 echo $ECHO_N "checking if your system defines WTMP_FILE... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_PATHS_H # include #endif int main () { char *wtmp = WTMP_FILE; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } system_wtmp_path=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test -z "$conf_wtmp_location"; then if test x"$system_wtmp_path" = x"no" ; then for f in /usr/adm/wtmp /var/log/wtmp; do if test -f $f ; then conf_wtmp_location=$f fi done if test -z "$conf_wtmp_location"; then cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMP 1 _ACEOF fi fi fi if test -n "$conf_wtmp_location"; then cat >>confdefs.h <<_ACEOF #define CONF_WTMP_FILE "$conf_wtmp_location" _ACEOF fi { echo "$as_me:$LINENO: checking if your system defines WTMPX_FILE" >&5 echo $ECHO_N "checking if your system defines WTMPX_FILE... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_PATHS_H # include #endif int main () { char *wtmpx = WTMPX_FILE; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } system_wtmpx_path=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test -z "$conf_wtmpx_location"; then if test x"$system_wtmpx_path" = x"no" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMPX 1 _ACEOF fi else cat >>confdefs.h <<_ACEOF #define CONF_WTMPX_FILE "$conf_wtmpx_location" _ACEOF fi if test ! -z "$blibpath" ; then LDFLAGS="$LDFLAGS $blibflags$blibpath" { echo "$as_me:$LINENO: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&5 echo "$as_me: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&2;} fi { echo "$as_me:$LINENO: checking for struct lastlog.ll_line" >&5 echo $ECHO_N "checking for struct lastlog.ll_line... $ECHO_C" >&6; } if test "${ac_cv_member_struct_lastlog_ll_line+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif int main () { static struct lastlog ac_aggr; if (ac_aggr.ll_line) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_lastlog_ll_line=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif int main () { static struct lastlog ac_aggr; if (sizeof ac_aggr.ll_line) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_lastlog_ll_line=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_lastlog_ll_line=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_lastlog_ll_line" >&5 echo "${ECHO_T}$ac_cv_member_struct_lastlog_ll_line" >&6; } if test $ac_cv_member_struct_lastlog_ll_line = yes; then : else if test x$SKIP_DISABLE_LASTLOG_DEFINE != "xyes" ; then cat >>confdefs.h <<\_ACEOF #define DISABLE_LASTLOG 1 _ACEOF fi fi { echo "$as_me:$LINENO: checking for struct utmp.ut_line" >&5 echo $ECHO_N "checking for struct utmp.ut_line... $ECHO_C" >&6; } if test "${ac_cv_member_struct_utmp_ut_line+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif int main () { static struct utmp ac_aggr; if (ac_aggr.ut_line) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_utmp_ut_line=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UTMP_H #include #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_LASTLOG_H #include #endif int main () { static struct utmp ac_aggr; if (sizeof ac_aggr.ut_line) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_utmp_ut_line=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_utmp_ut_line=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_utmp_ut_line" >&5 echo "${ECHO_T}$ac_cv_member_struct_utmp_ut_line" >&6; } if test $ac_cv_member_struct_utmp_ut_line = yes; then : else cat >>confdefs.h <<\_ACEOF #define DISABLE_UTMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define DISABLE_WTMP 1 _ACEOF fi CFLAGS="$CFLAGS $werror_flags" if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then TEST_SSH_IPV6=no else TEST_SSH_IPV6=yes fi { echo "$as_me:$LINENO: checking whether BROKEN_GETADDRINFO is declared" >&5 echo $ECHO_N "checking whether BROKEN_GETADDRINFO is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_BROKEN_GETADDRINFO+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { #ifndef BROKEN_GETADDRINFO (void) BROKEN_GETADDRINFO; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_BROKEN_GETADDRINFO=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_BROKEN_GETADDRINFO=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_BROKEN_GETADDRINFO" >&5 echo "${ECHO_T}$ac_cv_have_decl_BROKEN_GETADDRINFO" >&6; } if test $ac_cv_have_decl_BROKEN_GETADDRINFO = yes; then TEST_SSH_IPV6=no fi TEST_SSH_IPV6=$TEST_SSH_IPV6 TEST_MALLOC_OPTIONS=$TEST_MALLOC_OPTIONS UNSUPPORTED_ALGORITHMS=$unsupported_algorithms ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile survey.sh" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by OpenSSH $as_me Portable, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ OpenSSH config.status Portable configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "buildpkg.sh") CONFIG_FILES="$CONFIG_FILES buildpkg.sh" ;; "opensshd.init") CONFIG_FILES="$CONFIG_FILES opensshd.init" ;; "openssh.xml") CONFIG_FILES="$CONFIG_FILES openssh.xml" ;; "openbsd-compat/Makefile") CONFIG_FILES="$CONFIG_FILES openbsd-compat/Makefile" ;; "openbsd-compat/regress/Makefile") CONFIG_FILES="$CONFIG_FILES openbsd-compat/regress/Makefile" ;; "survey.sh") CONFIG_FILES="$CONFIG_FILES survey.sh" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim AWK!$AWK$ac_delim RANLIB!$RANLIB$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim AR!$AR$ac_delim ac_ct_AR!$ac_ct_AR$ac_delim CAT!$CAT$ac_delim KILL!$KILL$ac_delim PERL!$PERL$ac_delim SED!$SED$ac_delim ENT!$ENT$ac_delim TEST_MINUS_S_SH!$TEST_MINUS_S_SH$ac_delim SH!$SH$ac_delim GROFF!$GROFF$ac_delim NROFF!$NROFF$ac_delim MANDOC!$MANDOC$ac_delim TEST_SHELL!$TEST_SHELL$ac_delim MANFMT!$MANFMT$ac_delim PATH_GROUPADD_PROG!$PATH_GROUPADD_PROG$ac_delim PATH_USERADD_PROG!$PATH_USERADD_PROG$ac_delim MAKE_PACKAGE_SUPPORTED!$MAKE_PACKAGE_SUPPORTED$ac_delim STARTUP_SCRIPT_SHELL!$STARTUP_SCRIPT_SHELL$ac_delim LOGIN_PROGRAM_FALLBACK!$LOGIN_PROGRAM_FALLBACK$ac_delim PATH_PASSWD_PROG!$PATH_PASSWD_PROG$ac_delim LD!$LD$ac_delim PKGCONFIG!$PKGCONFIG$ac_delim LIBEDIT!$LIBEDIT$ac_delim TEST_SSH_ECC!$TEST_SSH_ECC$ac_delim COMMENT_OUT_ECC!$COMMENT_OUT_ECC$ac_delim SSH_PRIVSEP_USER!$SSH_PRIVSEP_USER$ac_delim SSHLIBS!$SSHLIBS$ac_delim SSHDLIBS!$SSHDLIBS$ac_delim KRB5CONF!$KRB5CONF$ac_delim GSSLIBS!$GSSLIBS$ac_delim K5LIBS!$K5LIBS$ac_delim PRIVSEP_PATH!$PRIVSEP_PATH$ac_delim xauth_path!$xauth_path$ac_delim STRIP_OPT!$STRIP_OPT$ac_delim XAUTH_PATH!$XAUTH_PATH$ac_delim MANTYPE!$MANTYPE$ac_delim mansubdir!$mansubdir$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF user_path!$user_path$ac_delim piddir!$piddir$ac_delim TEST_SSH_IPV6!$TEST_SSH_IPV6$ac_delim TEST_MALLOC_OPTIONS!$TEST_MALLOC_OPTIONS$ac_delim UNSUPPORTED_ALGORITHMS!$UNSUPPORTED_ALGORITHMS$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 7; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi # Print summary of options # Someone please show me a better way :) A=`eval echo ${prefix}` ; A=`eval echo ${A}` B=`eval echo ${bindir}` ; B=`eval echo ${B}` C=`eval echo ${sbindir}` ; C=`eval echo ${C}` D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}` E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}` F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}` G=`eval echo ${piddir}` ; G=`eval echo ${G}` H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}` I=`eval echo ${user_path}` ; I=`eval echo ${I}` J=`eval echo ${superuser_path}` ; J=`eval echo ${J}` echo "" echo "OpenSSH has been configured with the following options:" echo " User binaries: $B" echo " System binaries: $C" echo " Configuration files: $D" echo " Askpass program: $E" echo " Manual pages: $F" echo " PID file: $G" echo " Privilege separation chroot path: $H" if test "x$external_path_file" = "x/etc/login.conf" ; then echo " At runtime, sshd will use the path defined in $external_path_file" echo " Make sure the path to scp is present, otherwise scp will not work" else echo " sshd default user PATH: $I" if test ! -z "$external_path_file"; then echo " (If PATH is set in $external_path_file it will be used instead. If" echo " used, ensure the path to scp is present, otherwise scp will not work.)" fi fi if test ! -z "$superuser_path" ; then echo " sshd superuser user PATH: $J" fi echo " Manpage format: $MANTYPE" echo " PAM support: $PAM_MSG" echo " OSF SIA support: $SIA_MSG" echo " KerberosV support: $KRB5_MSG" echo " SELinux support: $SELINUX_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" echo " Solaris privilege support: $SPP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo "" echo " Host: ${host}" echo " Compiler: ${CC}" echo " Compiler flags: ${CFLAGS}" echo "Preprocessor flags: ${CPPFLAGS}" echo " Linker flags: ${LDFLAGS}" echo " Libraries: ${LIBS}" if test ! -z "${SSHDLIBS}"; then echo " +for sshd: ${SSHDLIBS}" fi if test ! -z "${SSHLIBS}"; then echo " +for ssh: ${SSHLIBS}" fi echo "" if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then echo "SVR4 style packages are supported with \"make package\"" echo "" fi if test "x$PAM_MSG" = "xyes" ; then echo "PAM is enabled. You may need to install a PAM control file " echo "for sshd, otherwise password authentication may fail. " echo "Example PAM control files can be found in the contrib/ " echo "subdirectory" echo "" fi if test ! -z "$NO_PEERCHECK" ; then echo "WARNING: the operating system that you are using does not" echo "appear to support getpeereid(), getpeerucred() or the" echo "SO_PEERCRED getsockopt() option. These facilities are used to" echo "enforce security checks to prevent unauthorised connections to" echo "ssh-agent. Their absence increases the risk that a malicious" echo "user can connect to your agent." echo "" fi if test "$AUDIT_MODULE" = "bsm" ; then echo "WARNING: BSM audit support is currently considered EXPERIMENTAL." echo "See the Solaris section in README.platform for details." fi openssh-7.2p2/config.h.in010064400017500001750000001312121267007037400135030ustar00djmdjm/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address */ #undef AIX_GETNAMEINFO_HACK /* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ #undef AIX_LOGINFAILED_4ARG /* System only supports IPv4 audit records */ #undef AU_IPv4 /* Define if your resolver libs need this for getrrsetbyname */ #undef BIND_8_COMPAT /* The system has incomplete BSM API */ #undef BROKEN_BSM_API /* Define if cmsg_type is not passed correctly */ #undef BROKEN_CMSG_TYPE /* getaddrinfo is broken (if present) */ #undef BROKEN_GETADDRINFO /* getgroups(0,NULL) will return -1 */ #undef BROKEN_GETGROUPS /* FreeBSD glob does not do what we need */ #undef BROKEN_GLOB /* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ #undef BROKEN_INET_NTOA /* ia_uinfo routines not supported by OS yet */ #undef BROKEN_LIBIAF /* Ultrix mmap can't map files */ #undef BROKEN_MMAP /* Define if your struct dirent expects you to allocate extra space for d_name */ #undef BROKEN_ONE_BYTE_DIRENT_D_NAME /* Can't do comparisons on readv */ #undef BROKEN_READV_COMPARISON /* NetBSD read function is sometimes redirected, breaking atomicio comparisons against it */ #undef BROKEN_READ_COMPARISON /* realpath does not work with nonexistent files */ #undef BROKEN_REALPATH /* Needed for NeXT */ #undef BROKEN_SAVED_UIDS /* Define if your setregid() is broken */ #undef BROKEN_SETREGID /* Define if your setresgid() is broken */ #undef BROKEN_SETRESGID /* Define if your setresuid() is broken */ #undef BROKEN_SETRESUID /* Define if your setreuid() is broken */ #undef BROKEN_SETREUID /* LynxOS has broken setvbuf() implementation */ #undef BROKEN_SETVBUF /* QNX shadow support is broken */ #undef BROKEN_SHADOW_EXPIRE /* Define if your snprintf is busted */ #undef BROKEN_SNPRINTF /* FreeBSD strnvis argument order is swapped compared to OpenBSD */ #undef BROKEN_STRNVIS /* tcgetattr with ICANON may hang */ #undef BROKEN_TCGETATTR_ICANON /* updwtmpx is broken (if present) */ #undef BROKEN_UPDWTMPX /* Define if you have BSD auth support */ #undef BSD_AUTH /* Define if you want to specify the path to your lastlog file */ #undef CONF_LASTLOG_FILE /* Define if you want to specify the path to your utmp file */ #undef CONF_UTMP_FILE /* Define if you want to specify the path to your wtmpx file */ #undef CONF_WTMPX_FILE /* Define if you want to specify the path to your wtmp file */ #undef CONF_WTMP_FILE /* Define if your platform needs to skip post auth file descriptor passing */ #undef DISABLE_FD_PASSING /* Define if you don't want to use lastlog */ #undef DISABLE_LASTLOG /* Define if you don't want to use your system's login() call */ #undef DISABLE_LOGIN /* Define if you don't want to use pututline() etc. to write [uw]tmp */ #undef DISABLE_PUTUTLINE /* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ #undef DISABLE_PUTUTXLINE /* Define if you want to disable shadow passwords */ #undef DISABLE_SHADOW /* Define if you don't want to use utmp */ #undef DISABLE_UTMP /* Define if you don't want to use utmpx */ #undef DISABLE_UTMPX /* Define if you don't want to use wtmp */ #undef DISABLE_WTMP /* Define if you don't want to use wtmpx */ #undef DISABLE_WTMPX /* Enable for PKCS#11 support */ #undef ENABLE_PKCS11 /* File names may not contain backslash characters */ #undef FILESYSTEM_NO_BACKSLASH /* fsid_t has member val */ #undef FSID_HAS_VAL /* fsid_t has member __val */ #undef FSID_HAS___VAL /* Define to 1 if the `getpgrp' function requires zero arguments. */ #undef GETPGRP_VOID /* Conflicting defs for getspnam */ #undef GETSPNAM_CONFLICTING_DEFS /* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ #undef GLOB_HAS_ALTDIRFUNC /* Define if your system glob() function has gl_matchc options in glob_t */ #undef GLOB_HAS_GL_MATCHC /* Define if your system glob() function has gl_statv options in glob_t */ #undef GLOB_HAS_GL_STATV /* Define this if you want GSSAPI support in the version 2 protocol */ #undef GSSAPI /* Define if you want to use shadow password expire field */ #undef HAS_SHADOW_EXPIRE /* Define if your system uses access rights style file descriptor passing */ #undef HAVE_ACCRIGHTS_IN_MSGHDR /* Define if you have ut_addr in utmp.h */ #undef HAVE_ADDR_IN_UTMP /* Define if you have ut_addr in utmpx.h */ #undef HAVE_ADDR_IN_UTMPX /* Define if you have ut_addr_v6 in utmp.h */ #undef HAVE_ADDR_V6_IN_UTMP /* Define if you have ut_addr_v6 in utmpx.h */ #undef HAVE_ADDR_V6_IN_UTMPX /* Define to 1 if you have the `arc4random' function. */ #undef HAVE_ARC4RANDOM /* Define to 1 if you have the `arc4random_buf' function. */ #undef HAVE_ARC4RANDOM_BUF /* Define to 1 if you have the `arc4random_stir' function. */ #undef HAVE_ARC4RANDOM_STIR /* Define to 1 if you have the `arc4random_uniform' function. */ #undef HAVE_ARC4RANDOM_UNIFORM /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* OpenBSD's gcc has bounded */ #undef HAVE_ATTRIBUTE__BOUNDED__ /* Have attribute nonnull */ #undef HAVE_ATTRIBUTE__NONNULL__ /* OpenBSD's gcc has sentinel */ #undef HAVE_ATTRIBUTE__SENTINEL__ /* Define to 1 if you have the `aug_get_machine' function. */ #undef HAVE_AUG_GET_MACHINE /* Define to 1 if you have the `b64_ntop' function. */ #undef HAVE_B64_NTOP /* Define to 1 if you have the `b64_pton' function. */ #undef HAVE_B64_PTON /* Define if you have the basename function. */ #undef HAVE_BASENAME /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY /* Define to 1 if you have the `bcrypt_pbkdf' function. */ #undef HAVE_BCRYPT_PBKDF /* Define to 1 if you have the `bindresvport_sa' function. */ #undef HAVE_BINDRESVPORT_SA /* Define to 1 if you have the `blf_enc' function. */ #undef HAVE_BLF_ENC /* Define to 1 if you have the header file. */ #undef HAVE_BLF_H /* Define to 1 if you have the `Blowfish_expand0state' function. */ #undef HAVE_BLOWFISH_EXPAND0STATE /* Define to 1 if you have the `Blowfish_expandstate' function. */ #undef HAVE_BLOWFISH_EXPANDSTATE /* Define to 1 if you have the `Blowfish_initstate' function. */ #undef HAVE_BLOWFISH_INITSTATE /* Define to 1 if you have the `Blowfish_stream2word' function. */ #undef HAVE_BLOWFISH_STREAM2WORD /* Define to 1 if you have the `BN_is_prime_ex' function. */ #undef HAVE_BN_IS_PRIME_EX /* Define to 1 if you have the header file. */ #undef HAVE_BSD_LIBUTIL_H /* Define to 1 if you have the header file. */ #undef HAVE_BSM_AUDIT_H /* Define to 1 if you have the header file. */ #undef HAVE_BSTRING_H /* Define to 1 if you have the `cap_rights_limit' function. */ #undef HAVE_CAP_RIGHTS_LIMIT /* Define to 1 if you have the `clock' function. */ #undef HAVE_CLOCK /* Have clock_gettime */ #undef HAVE_CLOCK_GETTIME /* define if you have clock_t data type */ #undef HAVE_CLOCK_T /* Define to 1 if you have the `closefrom' function. */ #undef HAVE_CLOSEFROM /* Define if gai_strerror() returns const char * */ #undef HAVE_CONST_GAI_STRERROR_PROTO /* Define if your system uses ancillary data style file descriptor passing */ #undef HAVE_CONTROL_IN_MSGHDR /* Define to 1 if you have the `crypt' function. */ #undef HAVE_CRYPT /* Define to 1 if you have the header file. */ #undef HAVE_CRYPTO_SHA2_H /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define if you are on Cygwin */ #undef HAVE_CYGWIN /* Define if your libraries define daemon() */ #undef HAVE_DAEMON /* Define to 1 if you have the declaration of `AI_NUMERICSERV', and to 0 if you don't. */ #undef HAVE_DECL_AI_NUMERICSERV /* Define to 1 if you have the declaration of `authenticate', and to 0 if you don't. */ #undef HAVE_DECL_AUTHENTICATE /* Define to 1 if you have the declaration of `GLOB_NOMATCH', and to 0 if you don't. */ #undef HAVE_DECL_GLOB_NOMATCH /* Define to 1 if you have the declaration of `GSS_C_NT_HOSTBASED_SERVICE', and to 0 if you don't. */ #undef HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE /* Define to 1 if you have the declaration of `howmany', and to 0 if you don't. */ #undef HAVE_DECL_HOWMANY /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO /* Define to 1 if you have the declaration of `loginfailed', and to 0 if you don't. */ #undef HAVE_DECL_LOGINFAILED /* Define to 1 if you have the declaration of `loginrestrictions', and to 0 if you don't. */ #undef HAVE_DECL_LOGINRESTRICTIONS /* Define to 1 if you have the declaration of `loginsuccess', and to 0 if you don't. */ #undef HAVE_DECL_LOGINSUCCESS /* Define to 1 if you have the declaration of `MAXSYMLINKS', and to 0 if you don't. */ #undef HAVE_DECL_MAXSYMLINKS /* Define to 1 if you have the declaration of `NFDBITS', and to 0 if you don't. */ #undef HAVE_DECL_NFDBITS /* Define to 1 if you have the declaration of `offsetof', and to 0 if you don't. */ #undef HAVE_DECL_OFFSETOF /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you don't. */ #undef HAVE_DECL_O_NONBLOCK /* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you don't. */ #undef HAVE_DECL_PASSWDEXPIRED /* Define to 1 if you have the declaration of `setauthdb', and to 0 if you don't. */ #undef HAVE_DECL_SETAUTHDB /* Define to 1 if you have the declaration of `SHUT_RD', and to 0 if you don't. */ #undef HAVE_DECL_SHUT_RD /* Define to 1 if you have the declaration of `writev', and to 0 if you don't. */ #undef HAVE_DECL_WRITEV /* Define to 1 if you have the declaration of `_getlong', and to 0 if you don't. */ #undef HAVE_DECL__GETLONG /* Define to 1 if you have the declaration of `_getshort', and to 0 if you don't. */ #undef HAVE_DECL__GETSHORT /* Define to 1 if you have the `DES_crypt' function. */ #undef HAVE_DES_CRYPT /* Define if you have /dev/ptmx */ #undef HAVE_DEV_PTMX /* Define if you have /dev/ptc */ #undef HAVE_DEV_PTS_AND_PTC /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the `dirfd' function. */ #undef HAVE_DIRFD /* Define to 1 if you have the `dirname' function. */ #undef HAVE_DIRNAME /* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ #undef HAVE_DSA_GENERATE_PARAMETERS_EX /* Define to 1 if you have the header file. */ #undef HAVE_ELF_H /* Define to 1 if you have the `endgrent' function. */ #undef HAVE_ENDGRENT /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if you have the `endutent' function. */ #undef HAVE_ENDUTENT /* Define to 1 if you have the `endutxent' function. */ #undef HAVE_ENDUTXENT /* Define if your system has /etc/default/login */ #undef HAVE_ETC_DEFAULT_LOGIN /* Define if libcrypto has EVP_CIPHER_CTX_ctrl */ #undef HAVE_EVP_CIPHER_CTX_CTRL /* Define to 1 if you have the `EVP_DigestFinal_ex' function. */ #undef HAVE_EVP_DIGESTFINAL_EX /* Define to 1 if you have the `EVP_DigestInit_ex' function. */ #undef HAVE_EVP_DIGESTINIT_EX /* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ #undef HAVE_EVP_MD_CTX_CLEANUP /* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */ #undef HAVE_EVP_MD_CTX_COPY_EX /* Define to 1 if you have the `EVP_MD_CTX_init' function. */ #undef HAVE_EVP_MD_CTX_INIT /* Define to 1 if you have the `EVP_ripemd160' function. */ #undef HAVE_EVP_RIPEMD160 /* Define to 1 if you have the `EVP_sha256' function. */ #undef HAVE_EVP_SHA256 /* Define if you have ut_exit in utmp.h */ #undef HAVE_EXIT_IN_UTMP /* Define to 1 if you have the `explicit_bzero' function. */ #undef HAVE_EXPLICIT_BZERO /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD /* Define to 1 if you have the `fchown' function. */ #undef HAVE_FCHOWN /* Use F_CLOSEM fcntl for closefrom */ #undef HAVE_FCNTL_CLOSEM /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if the system has the type `fd_mask'. */ #undef HAVE_FD_MASK /* Define to 1 if you have the header file. */ #undef HAVE_FEATURES_H /* Define to 1 if you have the header file. */ #undef HAVE_FLOATINGPOINT_H /* Define to 1 if you have the `fmt_scaled' function. */ #undef HAVE_FMT_SCALED /* Define to 1 if you have the `freeaddrinfo' function. */ #undef HAVE_FREEADDRINFO /* Define to 1 if the system has the type `fsblkcnt_t'. */ #undef HAVE_FSBLKCNT_T /* Define to 1 if the system has the type `fsfilcnt_t'. */ #undef HAVE_FSFILCNT_T /* Define to 1 if you have the `fstatfs' function. */ #undef HAVE_FSTATFS /* Define to 1 if you have the `fstatvfs' function. */ #undef HAVE_FSTATVFS /* Define to 1 if you have the `futimes' function. */ #undef HAVE_FUTIMES /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR /* Define to 1 if you have the `getaddrinfo' function. */ #undef HAVE_GETADDRINFO /* Define to 1 if you have the `getaudit' function. */ #undef HAVE_GETAUDIT /* Define to 1 if you have the `getaudit_addr' function. */ #undef HAVE_GETAUDIT_ADDR /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD /* Define to 1 if you have the `getgrouplist' function. */ #undef HAVE_GETGROUPLIST /* Define to 1 if you have the `getgrset' function. */ #undef HAVE_GETGRSET /* Define to 1 if you have the `getlastlogxbyname' function. */ #undef HAVE_GETLASTLOGXBYNAME /* Define to 1 if you have the `getluid' function. */ #undef HAVE_GETLUID /* Define to 1 if you have the `getnameinfo' function. */ #undef HAVE_GETNAMEINFO /* Define to 1 if you have the `getopt' function. */ #undef HAVE_GETOPT /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define if your getopt(3) defines and uses optreset */ #undef HAVE_GETOPT_OPTRESET /* Define if your libraries define getpagesize() */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `getpeereid' function. */ #undef HAVE_GETPEEREID /* Define to 1 if you have the `getpeerucred' function. */ #undef HAVE_GETPEERUCRED /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID /* Define to 1 if you have the `getpgrp' function. */ #undef HAVE_GETPGRP /* Define to 1 if you have the `getpwanam' function. */ #undef HAVE_GETPWANAM /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT /* Define if getrrsetbyname() exists */ #undef HAVE_GETRRSETBYNAME /* Define to 1 if you have the `getrusage' function. */ #undef HAVE_GETRUSAGE /* Define to 1 if you have the `getseuserbyname' function. */ #undef HAVE_GETSEUSERBYNAME /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `getttyent' function. */ #undef HAVE_GETTTYENT /* Define to 1 if you have the `getutent' function. */ #undef HAVE_GETUTENT /* Define to 1 if you have the `getutid' function. */ #undef HAVE_GETUTID /* Define to 1 if you have the `getutline' function. */ #undef HAVE_GETUTLINE /* Define to 1 if you have the `getutxent' function. */ #undef HAVE_GETUTXENT /* Define to 1 if you have the `getutxid' function. */ #undef HAVE_GETUTXID /* Define to 1 if you have the `getutxline' function. */ #undef HAVE_GETUTXLINE /* Define to 1 if you have the `getutxuser' function. */ #undef HAVE_GETUTXUSER /* Define to 1 if you have the `get_default_context_with_level' function. */ #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL /* Define to 1 if you have the `glob' function. */ #undef HAVE_GLOB /* Define to 1 if you have the header file. */ #undef HAVE_GLOB_H /* Define to 1 if you have the `group_from_gid' function. */ #undef HAVE_GROUP_FROM_GID /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GENERIC_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_GENERIC_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_KRB5_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_KRB5_H /* Define if HEADER.ad exists in arpa/nameser.h */ #undef HAVE_HEADER_AD /* Define to 1 if you have the `HMAC_CTX_init' function. */ #undef HAVE_HMAC_CTX_INIT /* Define if you have ut_host in utmp.h */ #undef HAVE_HOST_IN_UTMP /* Define if you have ut_host in utmpx.h */ #undef HAVE_HOST_IN_UTMPX /* Define to 1 if you have the header file. */ #undef HAVE_IAF_H /* Define to 1 if you have the header file. */ #undef HAVE_IA_H /* Define if you have ut_id in utmp.h */ #undef HAVE_ID_IN_UTMP /* Define if you have ut_id in utmpx.h */ #undef HAVE_ID_IN_UTMPX /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON /* Define to 1 if you have the `inet_ntoa' function. */ #undef HAVE_INET_NTOA /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `innetgr' function. */ #undef HAVE_INNETGR /* define if you have int64_t data type */ #undef HAVE_INT64_T /* Define to 1 if the system has the type `intmax_t'. */ #undef HAVE_INTMAX_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* define if you have intxx_t data type */ #undef HAVE_INTXX_T /* Define to 1 if the system has the type `in_addr_t'. */ #undef HAVE_IN_ADDR_T /* Define to 1 if the system has the type `in_port_t'. */ #undef HAVE_IN_PORT_T /* Define if you have isblank(3C). */ #undef HAVE_ISBLANK /* Define to 1 if you have the `krb5_cc_new_unique' function. */ #undef HAVE_KRB5_CC_NEW_UNIQUE /* Define to 1 if you have the `krb5_free_error_message' function. */ #undef HAVE_KRB5_FREE_ERROR_MESSAGE /* Define to 1 if you have the `krb5_get_error_message' function. */ #undef HAVE_KRB5_GET_ERROR_MESSAGE /* Define to 1 if you have the header file. */ #undef HAVE_LASTLOG_H /* Define if you want ldns support */ #undef HAVE_LDNS /* Define to 1 if you have the header file. */ #undef HAVE_LIBAUDIT_H /* Define to 1 if you have the `bsm' library (-lbsm). */ #undef HAVE_LIBBSM /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the header file. */ #undef HAVE_LIBGEN_H /* Define if system has libiaf that supports set_id */ #undef HAVE_LIBIAF /* Define to 1 if you have the `network' library (-lnetwork). */ #undef HAVE_LIBNETWORK /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_LIBUTIL_H /* Define to 1 if you have the `xnet' library (-lxnet). */ #undef HAVE_LIBXNET /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_AUDIT_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_FILTER_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SECCOMP_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `login' function. */ #undef HAVE_LOGIN /* Define to 1 if you have the header file. */ #undef HAVE_LOGIN_CAP_H /* Define to 1 if you have the `login_getcapbool' function. */ #undef HAVE_LOGIN_GETCAPBOOL /* Define to 1 if you have the header file. */ #undef HAVE_LOGIN_H /* Define to 1 if you have the `logout' function. */ #undef HAVE_LOGOUT /* Define to 1 if you have the `logwtmp' function. */ #undef HAVE_LOGWTMP /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE /* Define to 1 if the system has the type `long long'. */ #undef HAVE_LONG_LONG /* Define to 1 if you have the header file. */ #undef HAVE_MAILLOCK_H /* Define to 1 if you have the `mblen' function. */ #undef HAVE_MBLEN /* Define to 1 if you have the `md5_crypt' function. */ #undef HAVE_MD5_CRYPT /* Define if you want to allow MD5 passwords */ #undef HAVE_MD5_PASSWORDS /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset_s' function. */ #undef HAVE_MEMSET_S /* Define to 1 if you have the `mkdtemp' function. */ #undef HAVE_MKDTEMP /* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP /* define if you have mode_t data type */ #undef HAVE_MODE_T /* Some systems put nanosleep outside of libc */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the header file. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETGROUP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_TUN_H /* Define if you are on NeXT */ #undef HAVE_NEXT /* Define to 1 if you have the `ngetaddrinfo' function. */ #undef HAVE_NGETADDRINFO /* Define to 1 if you have the `nsleep' function. */ #undef HAVE_NSLEEP /* Define to 1 if you have the `ogetaddrinfo' function. */ #undef HAVE_OGETADDRINFO /* Define if you have an old version of PAM which takes only one argument to pam_strerror */ #undef HAVE_OLD_PAM /* Define to 1 if you have the `openlog_r' function. */ #undef HAVE_OPENLOG_R /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY /* Define if your ssl headers are included with #include */ #undef HAVE_OPENSSL /* Define if you have Digital Unix Security Integration Architecture */ #undef HAVE_OSF_SIA /* Define to 1 if you have the `pam_getenvlist' function. */ #undef HAVE_PAM_GETENVLIST /* Define to 1 if you have the header file. */ #undef HAVE_PAM_PAM_APPL_H /* Define to 1 if you have the `pam_putenv' function. */ #undef HAVE_PAM_PUTENV /* Define to 1 if you have the header file. */ #undef HAVE_PATHS_H /* Define if you have ut_pid in utmp.h */ #undef HAVE_PID_IN_UTMP /* define if you have pid_t data type */ #undef HAVE_PID_T /* Define to 1 if you have the `pledge' function. */ #undef HAVE_PLEDGE /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL /* Define to 1 if you have the `priv_basicset' function. */ #undef HAVE_PRIV_BASICSET /* Define to 1 if you have the header file. */ #undef HAVE_PRIV_H /* Define if you have /proc/$pid/fd */ #undef HAVE_PROC_PID /* Define to 1 if you have the `pstat' function. */ #undef HAVE_PSTAT /* Define to 1 if you have the header file. */ #undef HAVE_PTY_H /* Define to 1 if you have the `pututline' function. */ #undef HAVE_PUTUTLINE /* Define to 1 if you have the `pututxline' function. */ #undef HAVE_PUTUTXLINE /* Define to 1 if you have the `readpassphrase' function. */ #undef HAVE_READPASSPHRASE /* Define to 1 if you have the header file. */ #undef HAVE_READPASSPHRASE_H /* Define to 1 if you have the `reallocarray' function. */ #undef HAVE_REALLOCARRAY /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH /* Define to 1 if you have the `recvmsg' function. */ #undef HAVE_RECVMSG /* sys/resource.h has RLIMIT_NPROC */ #undef HAVE_RLIMIT_NPROC /* Define to 1 if you have the header file. */ #undef HAVE_RPC_TYPES_H /* Define to 1 if you have the `rresvport_af' function. */ #undef HAVE_RRESVPORT_AF /* Define to 1 if you have the `RSA_generate_key_ex' function. */ #undef HAVE_RSA_GENERATE_KEY_EX /* Define to 1 if you have the `RSA_get_default_method' function. */ #undef HAVE_RSA_GET_DEFAULT_METHOD /* Define to 1 if you have the header file. */ #undef HAVE_SANDBOX_H /* Define to 1 if you have the `sandbox_init' function. */ #undef HAVE_SANDBOX_INIT /* define if you have sa_family_t data type */ #undef HAVE_SA_FAMILY_T /* Define to 1 if you have the `scan_scaled' function. */ #undef HAVE_SCAN_SCALED /* Define if you have SecureWare-based protected password database */ #undef HAVE_SECUREWARE /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_H /* Define to 1 if you have the `sendmsg' function. */ #undef HAVE_SENDMSG /* Define to 1 if you have the `setauthdb' function. */ #undef HAVE_SETAUTHDB /* Define to 1 if you have the `setdtablesize' function. */ #undef HAVE_SETDTABLESIZE /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID /* Define to 1 if you have the `setgroupent' function. */ #undef HAVE_SETGROUPENT /* Define to 1 if you have the `setgroups' function. */ #undef HAVE_SETGROUPS /* Define to 1 if you have the `setlinebuf' function. */ #undef HAVE_SETLINEBUF /* Define to 1 if you have the `setlogin' function. */ #undef HAVE_SETLOGIN /* Define to 1 if you have the `setluid' function. */ #undef HAVE_SETLUID /* Define to 1 if you have the `setpassent' function. */ #undef HAVE_SETPASSENT /* Define to 1 if you have the `setpcred' function. */ #undef HAVE_SETPCRED /* Define to 1 if you have the `setppriv' function. */ #undef HAVE_SETPPRIV /* Define to 1 if you have the `setproctitle' function. */ #undef HAVE_SETPROCTITLE /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID /* Define to 1 if you have the `setresgid' function. */ #undef HAVE_SETRESGID /* Define to 1 if you have the `setresuid' function. */ #undef HAVE_SETRESUID /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the `setrlimit' function. */ #undef HAVE_SETRLIMIT /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `setutent' function. */ #undef HAVE_SETUTENT /* Define to 1 if you have the `setutxdb' function. */ #undef HAVE_SETUTXDB /* Define to 1 if you have the `setutxent' function. */ #undef HAVE_SETUTXENT /* Define to 1 if you have the `setvbuf' function. */ #undef HAVE_SETVBUF /* Define to 1 if you have the `set_id' function. */ #undef HAVE_SET_ID /* Define to 1 if you have the `SHA256_Update' function. */ #undef HAVE_SHA256_UPDATE /* Define to 1 if you have the header file. */ #undef HAVE_SHA2_H /* Define to 1 if you have the header file. */ #undef HAVE_SHADOW_H /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the `sigvec' function. */ #undef HAVE_SIGVEC /* Define to 1 if the system has the type `sig_atomic_t'. */ #undef HAVE_SIG_ATOMIC_T /* define if you have size_t data type */ #undef HAVE_SIZE_T /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `socketpair' function. */ #undef HAVE_SOCKETPAIR /* Have PEERCRED socket option */ #undef HAVE_SO_PEERCRED /* define if you have ssize_t data type */ #undef HAVE_SSIZE_T /* Fields in struct sockaddr_storage */ #undef HAVE_SS_FAMILY_IN_SS /* Define to 1 if you have the `statfs' function. */ #undef HAVE_STATFS /* Define to 1 if you have the `statvfs' function. */ #undef HAVE_STATVFS /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Silly mkstemp() */ #undef HAVE_STRICT_MKSTEMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the `strmode' function. */ #undef HAVE_STRMODE /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN /* Define to 1 if you have the `strnvis' function. */ #undef HAVE_STRNVIS /* Define to 1 if you have the `strptime' function. */ #undef HAVE_STRPTIME /* Define to 1 if you have the `strsep' function. */ #undef HAVE_STRSEP /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL /* Define to 1 if you have the `strtonum' function. */ #undef HAVE_STRTONUM /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the `strtoull' function. */ #undef HAVE_STRTOULL /* define if you have struct addrinfo data type */ #undef HAVE_STRUCT_ADDRINFO /* define if you have struct in6_addr data type */ #undef HAVE_STRUCT_IN6_ADDR /* Define to 1 if `pw_change' is member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_CHANGE /* Define to 1 if `pw_class' is member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_CLASS /* Define to 1 if `pw_expire' is member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_EXPIRE /* Define to 1 if `pw_gecos' is member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_GECOS /* define if you have struct sockaddr_in6 data type */ #undef HAVE_STRUCT_SOCKADDR_IN6 /* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */ #undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID /* define if you have struct sockaddr_storage data type */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if `st_blksize' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLKSIZE /* Define to 1 if the system has the type `struct timespec'. */ #undef HAVE_STRUCT_TIMESPEC /* define if you have struct timeval */ #undef HAVE_STRUCT_TIMEVAL /* Define to 1 if you have the `swap32' function. */ #undef HAVE_SWAP32 /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define if you have syslen in utmpx.h */ #undef HAVE_SYSLEN_IN_UTMPX /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BITYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CAPABILITY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CDEFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define if your system defines sys_errlist[] */ #undef HAVE_SYS_ERRLIST /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MOUNT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define if your system defines sys_nerr */ #undef HAVE_SYS_NERR /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PTMS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STREAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STROPTS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STRTIO_H /* Force use of sys/syslog.h on Ultrix */ #undef HAVE_SYS_SYSLOG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSMACROS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIMERS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have the `tcgetpgrp' function. */ #undef HAVE_TCGETPGRP /* Define to 1 if you have the `tcsendbreak' function. */ #undef HAVE_TCSENDBREAK /* Define to 1 if you have the `time' function. */ #undef HAVE_TIME /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define if you have ut_time in utmp.h */ #undef HAVE_TIME_IN_UTMP /* Define if you have ut_time in utmpx.h */ #undef HAVE_TIME_IN_UTMPX /* Define to 1 if you have the `timingsafe_bcmp' function. */ #undef HAVE_TIMINGSAFE_BCMP /* Define to 1 if you have the header file. */ #undef HAVE_TMPDIR_H /* Define to 1 if you have the `truncate' function. */ #undef HAVE_TRUNCATE /* Define to 1 if you have the header file. */ #undef HAVE_TTYENT_H /* Define if you have ut_tv in utmp.h */ #undef HAVE_TV_IN_UTMP /* Define if you have ut_tv in utmpx.h */ #undef HAVE_TV_IN_UTMPX /* Define if you have ut_type in utmp.h */ #undef HAVE_TYPE_IN_UTMP /* Define if you have ut_type in utmpx.h */ #undef HAVE_TYPE_IN_UTMPX /* Define to 1 if you have the header file. */ #undef HAVE_UCRED_H /* Define to 1 if the system has the type `uintmax_t'. */ #undef HAVE_UINTMAX_T /* define if you have uintxx_t data type */ #undef HAVE_UINTXX_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if the system has the type `unsigned long long'. */ #undef HAVE_UNSIGNED_LONG_LONG /* Define to 1 if you have the `updwtmp' function. */ #undef HAVE_UPDWTMP /* Define to 1 if you have the `updwtmpx' function. */ #undef HAVE_UPDWTMPX /* Define to 1 if you have the header file. */ #undef HAVE_USERSEC_H /* Define to 1 if you have the `user_from_uid' function. */ #undef HAVE_USER_FROM_UID /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP /* Define to 1 if you have the header file. */ #undef HAVE_UTIL_H /* Define to 1 if you have the `utimes' function. */ #undef HAVE_UTIMES /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H /* Define to 1 if you have the `utmpname' function. */ #undef HAVE_UTMPNAME /* Define to 1 if you have the `utmpxname' function. */ #undef HAVE_UTMPXNAME /* Define to 1 if you have the header file. */ #undef HAVE_UTMPX_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H /* define if you have u_char data type */ #undef HAVE_U_CHAR /* define if you have u_int data type */ #undef HAVE_U_INT /* define if you have u_int64_t data type */ #undef HAVE_U_INT64_T /* define if you have u_intxx_t data type */ #undef HAVE_U_INTXX_T /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Define if va_copy exists */ #undef HAVE_VA_COPY /* Define to 1 if you have the header file. */ #undef HAVE_VIS_H /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID /* Define to 1 if you have the `_getlong' function. */ #undef HAVE__GETLONG /* Define to 1 if you have the `_getpty' function. */ #undef HAVE__GETPTY /* Define to 1 if you have the `_getshort' function. */ #undef HAVE__GETSHORT /* Define if you have struct __res_state _res as an extern */ #undef HAVE__RES_EXTERN /* Define to 1 if you have the `__b64_ntop' function. */ #undef HAVE___B64_NTOP /* Define to 1 if you have the `__b64_pton' function. */ #undef HAVE___B64_PTON /* Define if compiler implements __FUNCTION__ */ #undef HAVE___FUNCTION__ /* Define if libc defines __progname */ #undef HAVE___PROGNAME /* Fields in struct sockaddr_storage */ #undef HAVE___SS_FAMILY_IN_SS /* Define if __va_copy exists */ #undef HAVE___VA_COPY /* Define if compiler implements __func__ */ #undef HAVE___func__ /* Define this if you are using the Heimdal version of Kerberos V5 */ #undef HEIMDAL /* Define if you need to use IP address instead of hostname in $DISPLAY */ #undef IPADDR_IN_DISPLAY /* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ #undef IPV4_IN_IPV6 /* Define if your system choked on IP TOS setting */ #undef IP_TOS_IS_BROKEN /* Define if you want Kerberos 5 support */ #undef KRB5 /* Define if pututxline updates lastlog too */ #undef LASTLOG_WRITE_PUTUTXLINE /* Define to whatever link() returns for "not supported" if it doesn't return EOPNOTSUPP. */ #undef LINK_OPNOTSUPP_ERRNO /* Adjust Linux out-of-memory killer */ #undef LINUX_OOM_ADJUST /* max value of long long calculated by configure */ #undef LLONG_MAX /* min value of long long calculated by configure */ #undef LLONG_MIN /* Account locked with pw(1) */ #undef LOCKED_PASSWD_PREFIX /* String used in /etc/passwd to denote locked account */ #undef LOCKED_PASSWD_STRING /* String used in /etc/passwd to denote locked account */ #undef LOCKED_PASSWD_SUBSTR /* Some versions of /bin/login need the TERM supplied on the commandline */ #undef LOGIN_NEEDS_TERM /* Some systems need a utmpx entry for /bin/login to work */ #undef LOGIN_NEEDS_UTMPX /* Define if your login program cannot handle end of options ("--") */ #undef LOGIN_NO_ENDOPT /* If your header files don't define LOGIN_PROGRAM, then use this (detected) from environment and PATH */ #undef LOGIN_PROGRAM_FALLBACK /* Set this to your mail directory if you do not have _PATH_MAILDIR */ #undef MAIL_DIRECTORY /* Need setpgrp to acquire controlling tty */ #undef NEED_SETPGRP /* compiler does not accept __attribute__ on return types */ #undef NO_ATTRIBUTE_ON_RETURN_TYPE /* Define if the concept of ports only accessible to superusers isn't known */ #undef NO_IPPORT_RESERVED_CONCEPT /* Define if you don't want to use lastlog in session.c */ #undef NO_SSH_LASTLOG /* Define to disable UID restoration test */ #undef NO_UID_RESTORATION_TEST /* Define if X11 doesn't support AF_UNIX sockets on that system */ #undef NO_X11_UNIX_SOCKETS /* Define if EVP_DigestUpdate returns void */ #undef OPENSSL_EVP_DIGESTUPDATE_VOID /* OpenSSL has ECC */ #undef OPENSSL_HAS_ECC /* libcrypto has NID_X9_62_prime256v1 */ #undef OPENSSL_HAS_NISTP256 /* libcrypto has NID_secp384r1 */ #undef OPENSSL_HAS_NISTP384 /* libcrypto has NID_secp521r1 */ #undef OPENSSL_HAS_NISTP521 /* libcrypto has EVP AES CTR */ #undef OPENSSL_HAVE_EVPCTR /* libcrypto has EVP AES GCM */ #undef OPENSSL_HAVE_EVPGCM /* libcrypto is missing AES 192 and 256 bit functions */ #undef OPENSSL_LOBOTOMISED_AES /* Define if you want the OpenSSL internally seeded PRNG only */ #undef OPENSSL_PRNG_ONLY /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define if you are using Solaris-derived PAM which passes pam_messages to the conversation function with an extra level of indirection */ #undef PAM_SUN_CODEBASE /* Work around problematic Linux PAM modules handling of PAM_TTY */ #undef PAM_TTY_KLUDGE /* must supply username to passwd */ #undef PASSWD_NEEDS_USERNAME /* System dirs owned by bin (uid 2) */ #undef PLATFORM_SYS_DIR_UID /* Port number of PRNGD/EGD random number socket */ #undef PRNGD_PORT /* Location of PRNGD/EGD random number socket */ #undef PRNGD_SOCKET /* read(1) can return 0 for a non-closed fd */ #undef PTY_ZEROREAD /* Sandbox using capsicum */ #undef SANDBOX_CAPSICUM /* Sandbox using Darwin sandbox_init(3) */ #undef SANDBOX_DARWIN /* no privsep sandboxing */ #undef SANDBOX_NULL /* Sandbox using pledge(2) */ #undef SANDBOX_PLEDGE /* Sandbox using setrlimit(2) */ #undef SANDBOX_RLIMIT /* Sandbox using seccomp filter */ #undef SANDBOX_SECCOMP_FILTER /* setrlimit RLIMIT_FSIZE works */ #undef SANDBOX_SKIP_RLIMIT_FSIZE /* define if setrlimit RLIMIT_NOFILE breaks things */ #undef SANDBOX_SKIP_RLIMIT_NOFILE /* Sandbox using Solaris/Illumos privileges */ #undef SANDBOX_SOLARIS /* Sandbox using systrace(4) */ #undef SANDBOX_SYSTRACE /* Specify the system call convention in use */ #undef SECCOMP_AUDIT_ARCH /* Define if your platform breaks doing a seteuid before a setuid */ #undef SETEUID_BREAKS_SETUID /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long int', as computed by sizeof. */ #undef SIZEOF_LONG_INT /* The size of `long long int', as computed by sizeof. */ #undef SIZEOF_LONG_LONG_INT /* The size of `short int', as computed by sizeof. */ #undef SIZEOF_SHORT_INT /* Define if you want S/Key support */ #undef SKEY /* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ #undef SKEYCHALLENGE_4ARG /* Define as const if snprintf() can declare const char *fmt */ #undef SNPRINTF_CONST /* Define to a Set Process Title type if your system is supported by bsd-setproctitle.c */ #undef SPT_TYPE /* Define if sshd somehow reacquires a controlling TTY after setsid() */ #undef SSHD_ACQUIRES_CTTY /* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ #undef SSHPAM_CHAUTHTOK_NEEDS_RUID /* Use audit debugging module */ #undef SSH_AUDIT_EVENTS /* Windows is sensitive to read buffer size */ #undef SSH_IOBUFSZ /* non-privileged user for privilege separation */ #undef SSH_PRIVSEP_USER /* Use tunnel device compatibility to OpenBSD */ #undef SSH_TUN_COMPAT_AF /* Open tunnel devices the FreeBSD way */ #undef SSH_TUN_FREEBSD /* Open tunnel devices the Linux tun/tap way */ #undef SSH_TUN_LINUX /* No layer 2 tunnel support */ #undef SSH_TUN_NO_L2 /* Open tunnel devices the OpenBSD way */ #undef SSH_TUN_OPENBSD /* Prepend the address family to IP tunnel traffic */ #undef SSH_TUN_PREPEND_AF /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you want a different $PATH for the superuser */ #undef SUPERUSER_PATH /* syslog_r function is safe to use in in a signal handler */ #undef SYSLOG_R_SAFE_IN_SIGHAND /* Support passwords > 8 chars */ #undef UNIXWARE_LONG_PASSWORDS /* Specify default $PATH */ #undef USER_PATH /* Define this if you want to use libkafs' AFS support */ #undef USE_AFS /* Use BSM audit module */ #undef USE_BSM_AUDIT /* Use btmp to log bad logins */ #undef USE_BTMP /* Use libedit for sftp */ #undef USE_LIBEDIT /* Use Linux audit module */ #undef USE_LINUX_AUDIT /* Enable OpenSSL engine support */ #undef USE_OPENSSL_ENGINE /* Define if you want to enable PAM support */ #undef USE_PAM /* Use PIPES instead of a socketpair() */ #undef USE_PIPES /* Define if you have Solaris privileges */ #undef USE_SOLARIS_PRIVS /* Define if you have Solaris process contracts */ #undef USE_SOLARIS_PROCESS_CONTRACTS /* Define if you have Solaris projects */ #undef USE_SOLARIS_PROJECTS /* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ #undef WITH_ABBREV_NO_TTY /* Define if you want to enable AIX4's authenticate function */ #undef WITH_AIXAUTHENTICATE /* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ #undef WITH_IRIX_ARRAY /* Define if you want IRIX audit trails */ #undef WITH_IRIX_AUDIT /* Define if you want IRIX kernel jobs */ #undef WITH_IRIX_JOBS /* Define if you want IRIX project management */ #undef WITH_IRIX_PROJECT /* use libcrypto for cryptography */ #undef WITH_OPENSSL /* Define if you want SELinux support. */ #undef WITH_SELINUX /* include SSH protocol version 1 support */ #undef WITH_SSH1 /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* Define if xauth is found in your path */ #undef XAUTH_PATH /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* log for bad login attempts */ #undef _PATH_BTMP /* Full path of your "passwd" program */ #undef _PATH_PASSWD_PROG /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR /* Define if we don't have struct __res_state in resolv.h */ #undef __res_state /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* type to use in place of socklen_t if not defined */ #undef socklen_t